این راهنما ساختار کلی پروژه امیر و نحوه سازماندهی کدها را توضیح میدهد.
امیر بر اساس Laravel Framework پیادهسازی شده و از معماری MVC پیروی میکند.
FreeAmir/
├── app/ # منطق اصلی اپلیکیشن
│ ├── Console/ # دستورات Artisan سفارشی
│ ├── Enums/ # انواع دادههای ثابت
│ ├── Exceptions/ # مدیریت خطاهای سفارشی
│ ├── Helpers/ # توابع کمکی
│ ├── Http/ # کنترلرها، میدلویرها و درخواستها
│ ├── Models/ # مدلهای Eloquent
│ ├── Providers/ # ارائهدهندگان سرویس
│ ├── Services/ # منطق کسبوکار پیچیده
│ └── View/ # کامپوننتهای View
├── config/ # فایلهای پیکربندی
├── database/ # مایگریشنها و سیدرها
├── docs/ # مستندات پروژه
├── public/ # فایلهای عمومی
├── resources/ # ویوها، CSS، JS
├── routes/ # تعریف مسیرها
├── storage/ # فایلهای موقت و لاگها
├── tests/ # تستهای خودکار
└── vendor/ # پکیجهای Composer
app/ - هسته اپلیکیشنConsole/Commands/دستورات سفارشی Artisan برای عملیات خاص:
// Example: دستور مدیریت سال مالی
php artisan fiscal-year:export --year=1403
php artisan fiscal-year:import --file=data.json --year=1404
Enums/انواع دادههای ثابت پروژه:
// app/Enums/FiscalYearSection.php
enum FiscalYearSection: string
{
case SUBJECTS = 'subjects';
case CUSTOMERS = 'customers';
case PRODUCTS = 'products';
// ...
}
Exceptions/خطاهای سفارشی:
// app/Exceptions/DocumentServiceException.php
class DocumentServiceException extends Exception
{
// منطق خاص برای خطاهای سند حسابداری
}
Helpers/توابع کمکی عمومی:
helpers.php - توابع عمومیjdf.php - توابع تبدیل تاریخ فارسیNumberToWordHelper.php - تبدیل عدد به حروفHttp/لایه HTTP اپلیکیشن:
Http/
├── Controllers/ # کنترلرها
│ ├── Auth/ # احراز هویت
│ ├── Management/ # مدیریت کاربران و نقشها
│ ├── DocumentController.php
│ ├── InvoiceController.php
│ └── ...
├── Middleware/ # میدلویرها
├── Requests/ # اعتبارسنجی درخواستها
└── Kernel.php # تنظیمات HTTP
Models/مدلهای Eloquent موجود در همین پوشه منطق داده را مدیریت میکنند. مهمترین فایلها عبارتاند از:
Document.php – مدیریت اسناد حسابداری و ارتباط آنها با تراکنشها.Transaction.php – ثبت تراکنشهای مرتبط با اسناد و سناریوهای فروش.Subject.php – ساختار درختی سرفصلها و روابط والد/فرزند آنها.Company.php – اطلاعات شرکت و نگهداشتن شناسه شرکت فعال.User.php – کاربران سیستم و ارتباط آنها با شرکتها.Customer.php و CustomerGroup.php – مدیریت مشتریان و گروهبندی آنها.Product.php و ProductGroup.php – کالاها و گروههای کالایی.Invoice.php و InvoiceItem.php – فاکتورهای فروش و اقلامشان.Bank.php، BankAccount.php، Cheque.php و ChequeHistory.php – مدیریت اطلاعات بانکی و چکها.Config.php و Payment.php – پیکربندی سیستم و پرداختها.زیرپوشه Scopes/ شامل FiscalYearScope.php است که بر روی مدلهای مرتبط اعمال میشود تا دادهها به شرکت/سال فعال محدود شوند.
نکته: مدلی با نام
FiscalYear.phpدر پروژه وجود ندارد؛ مدیریت سال/شرکت فعال از طریق مدلCompanyو همین اسکوپ انجام میشود.
Services/منطق کسبوکار پیچیده:
// app/Services/DocumentService.php
class DocumentService
{
public static function createDocument(User $user, array $data, array $transactions)
{
// منطق ایجاد سند با کنترل موازنه
}
}
// app/Services/FiscalYearService.php
class FiscalYearService
{
public static function exportData($fiscalYearId, array $sections)
{
// صادرات دادههای سال مالی
}
}
config/)فایلهای پیکربندی مهم:
// config/app.php - تنظیمات کلی
'locale' => 'fa', // زبان پیشفرض فارسی
// config/database.php - تنظیمات پایگاه داده
'default' => env('DB_CONNECTION', 'mysql'),
// config/permission.php - تنظیمات نقشها و مجوزها
database/)migrations/تعریف ساختار جداول:
// Example: مایگریشن جدول documents
Schema::create('documents', function (Blueprint $table) {
$table->id();
$table->decimal('number', 16, 2)->nullable();
$table->string('title')->nullable();
$table->date('date')->nullable();
$table->date('approved_at')->nullable();
$table->foreignId('creator_id')->nullable()->constrained('users')->nullOnDelete();
$table->foreignId('approver_id')->nullable()->constrained('users')->nullOnDelete();
$table->foreignId('company_id')->nullable()->constrained()->nullOnDelete();
$table->timestamps();
});
seeders/دادههای اولیه:
DatabaseSeeder.php - دادههای ضروری سیستمDemoSeeder.php - دادههای نمایشیresources/)views/قالبهای Blade:
views/
├── layouts/ # قالبهای اصلی
├── documents/ # صفحات مربوط به اسناد
├── reports/ # صفحات گزارشها
├── auth/ # صفحات احراز هویت
└── components/ # کامپوننتهای قابل استفاده مجدد
js/ و css/فایلهای JavaScript و CSS با Vite مدیریت میشوند.
routes/)web.phpمسیرهای وب اپلیکیشن:
Route::get('/login', [Controllers\Auth\LoginController::class, 'showLoginForm'])->name('login');
Route::post('/login', [Controllers\Auth\LoginController::class, 'login']);
Route::get('/logout', [Controllers\Auth\LoginController::class, 'logout'])->name('logout');
Route::group(['middleware' => ['auth', 'check-permission']], function () {
Route::get('/', [Controllers\HomeController::class, 'index'])->name('home');
Route::post('/home/subject-detail', [Controllers\HomeController::class, 'subjectDetail'])->name('home.subject-detail');
Route::resource('subjects', Controllers\SubjectController::class);
Route::post('subjects/search', [Controllers\SubjectController::class, 'search'])->name('subjects.search');
Route::resource('documents', Controllers\DocumentController::class);
Route::resource('transactions', Controllers\TransactionController::class)->only(['index', 'show']);
Route::resource('products', Controllers\ProductController::class);
Route::resource('product-groups', Controllers\ProductGroupController::class);
Route::resource('customers', Controllers\CustomerController::class);
Route::resource('customer-groups', Controllers\CustomerGroupController::class);
Route::resource('companies', Controllers\CompanyController::class);
Route::resource('bank-accounts', Controllers\BankAccountController::class);
Route::resource('banks', Controllers\BankController::class);
Route::resource('invoices', Controllers\InvoiceController::class)->except(['index', 'create']);
Route::group(['prefix' => 'management'], function () {
Route::resource('users', Controllers\Management\UserController::class);
Route::resource('permissions', Controllers\Management\PermissionController::class)->except(['show']);
Route::resource('roles', Controllers\Management\RoleController::class)->except(['show']);
Route::resource('configs', Controllers\ConfigController::class);
});
Route::group(['prefix' => 'reports', 'as' => 'reports.'], function () {
Route::get('ledger', [Controllers\ReportsController::class, 'ledger'])->name('ledger');
Route::get('journal', [Controllers\ReportsController::class, 'journal'])->name('journal');
Route::get('sub-ledger', [Controllers\ReportsController::class, 'subLedger'])->name('sub-ledger');
Route::get('documents', [Controllers\ReportsController::class, 'documents'])->name('documents');
Route::get('result', [Controllers\ReportsController::class, 'result'])->name('result');
});
Route::get('change-company/{company}', [Controllers\CompanyController::class, 'setActiveCompany'])->name('change-company');
Route::group(['prefix' => 'invoices/create', 'as' => 'invoices.create'], function () {
Route::get('{invoice_type}',[Controllers\InvoiceController::class, 'create']);
});
Route::group(['prefix' => 'invoices', 'as' => 'invoices.index'], function () {
Route::get('',[Controllers\InvoiceController::class, 'index']);
});
});
api.phpمسیرهای API:
Route::middleware('auth:sanctum')->get('/user', function (Request $request) {
return $request->user();
});
در حال حاضر فایل تنها شامل نمونهی پیشفرض لاراول است و میتوانید مسیرهای API جدید را در همین گروه اضافه کنید.
tests/)ساختار تستها مطابق استاندارد لاراول است و دو تست نمونه به صورت پیشفرض در مخزن حضور دارند:
tests/
├── Feature/ExampleTest.php # بررسی پاسخ موفق صفحهی اصلی
└── Unit/ExampleTest.php # تست ساده صحت true
برای گسترش پوشش تستها میتوانید فایلهای جدید با دستور php artisan make:test بسازید یا همین نمونهها را ویرایش کنید. راهنمای تست در docs/testing-guide.md توضیحات بیشتری ارائه میدهد.
مدیریت dependency های PHP:
composer install # نصب پکیجها
composer dump-autoload # بازسازی autoloader
composer update # بهروزرسانی پکیجها
مدیریت dependency های JavaScript:
npm install # نصب پکیجها
npm run dev # اجرای توسعه
npm run build # ساخت نهایی
دستورات Laravel:
php artisan migrate # اجرای مایگریشنها
php artisan db:seed # اجرای سیدرها
php artisan make:model # ایجاد مدل جدید
php artisan serve # اجرای سرور توسعه
PascalCase + Controller (مثل DocumentController)PascalCase منفرد (مثل Document)PascalCase + Service (مثل DocumentService)kebab-case (مثل document-create.blade.php)snake_case (مثل 2024_01_01_create_documents_table)camelCase (مثل $fiscalYear)snake_case (مثل fiscal_year_id)kebab-case (مثل /customer-groups)dot.notation (مثل documents.create)auth - احراز هویت کاربرcheck-permission - کنترل مجوزهااستفاده از پکیج Spatie Permission:
// permission in Controller
$this->authorize('documents.create');
// کنترل در Blade
@can('documents.edit')
<button>ویرایش</button>
@endcan
php artisan config:cachephp artisan route:cachephp artisan view:cacheنکته مهم: همیشه قبل از اعمال تغییرات، ساختار پروژه موجود را مطالعه کنید و از الگوهای استفاده شده پیروی کنید.