refactor(api): relocate StaffApiMiddleware and update routes
Move StaffApiMiddleware from the Controllers directory to the correct Middleware directory to adhere to Laravel directory structure standards. - Relocate StaffApiMiddleware from `app/Http/Controllers` to `app/Http/Middleware` - Update `api.php` to use the correct namespace for `StaffApiMiddleware` - Add `IFNEX_Logistics_Review_Workflow_HANDOFF.md` documentation for the review workflow
This commit is contained in:
parent
61a2643dd0
commit
69800a2b1e
@ -9,6 +9,7 @@ use App\Services\ShipmentReviewService;
|
||||
use Illuminate\Http\JsonResponse;
|
||||
use Illuminate\Http\Request;
|
||||
use Illuminate\Support\Facades\Auth;
|
||||
use App\Enums\ShipmentStatus;
|
||||
|
||||
class StaffOrderController extends Controller
|
||||
{
|
||||
|
||||
@ -12,9 +12,11 @@ use App\Http\Controllers\Api\StaffOrderController;
|
||||
use App\Http\Controllers\Api\TrackController;
|
||||
use App\Http\Controllers\Api\WalletController;
|
||||
use App\Http\Middleware\ApiKeyMiddleware;
|
||||
use App\Http\Middleware\StaffApiMiddleware;
|
||||
use Illuminate\Support\Facades\Route;
|
||||
use App\Http\Controllers\Api\AuthController;
|
||||
use App\Http\Controllers\Api\BridgeAuthController;
|
||||
use App\Http\Controllers\ShipmentPdfController;
|
||||
|
||||
|
||||
// ══════════════════════════════════════════════════════════════
|
||||
@ -97,7 +99,7 @@ Route::middleware(['auth:sanctum'])->prefix('v1')->group(function () {
|
||||
});
|
||||
|
||||
// ─── Staff Orders API (تأیید سفارشات) ───
|
||||
Route::middleware([\App\Http\Middleware\StaffApiMiddleware::class])
|
||||
Route::middleware([StaffApiMiddleware::class])
|
||||
->prefix('staff')
|
||||
->group(function () {
|
||||
|
||||
|
||||
635
IFNEX_Logistics_Review_Workflow_HANDOFF.md
Normal file
635
IFNEX_Logistics_Review_Workflow_HANDOFF.md
Normal file
@ -0,0 +1,635 @@
|
||||
# IFNEX Logistics — Review Workflow & Continuation Handoff
|
||||
|
||||
## وضعیت پروژه
|
||||
|
||||
مسیر Laravel:
|
||||
`C:\xampp\htdocs\IFNEX-Logistics\04_Laravel`
|
||||
|
||||
هدف فعلی: تکمیل Client Delivery و Hardening؛ سپس Productization.
|
||||
|
||||
---
|
||||
|
||||
## 1. Review Architecture
|
||||
|
||||
Review از Shipment Operational Status جدا شده است.
|
||||
|
||||
Review State:
|
||||
- `pending`
|
||||
- `changes_requested`
|
||||
- `approved`
|
||||
- `rejected`
|
||||
|
||||
جریان:
|
||||
|
||||
```text
|
||||
Create Order
|
||||
-> review_state=pending / status=pending_approval
|
||||
-> Staff Review
|
||||
-> Request Changes -> Customer Edit -> Resubmit -> pending
|
||||
-> Approve -> review_state=approved / status=approved
|
||||
-> Reject -> review_state=rejected / status=cancelled
|
||||
```
|
||||
|
||||
Review History با مدل `ShipmentReview` و revision مستقل نگهداری میشود و جایگزین `ShipmentStatusHistory` نیست.
|
||||
|
||||
---
|
||||
|
||||
## 2. وضعیت Filament
|
||||
|
||||
در لیست مرسولات Actionها ساخته و تست شدهاند:
|
||||
|
||||
- نمایش
|
||||
- ویرایش
|
||||
- تأیید
|
||||
- درخواست اصلاح
|
||||
- رد سفارش
|
||||
|
||||
Approve تست شده:
|
||||
- Dialog تأیید نمایش داده شد.
|
||||
- پیام موفقیت نمایش داده شد.
|
||||
- Status به `Approved` تغییر کرد.
|
||||
- Actionهای Review از ردیف حذف شدند.
|
||||
- مشتری پس از تأیید وارد مرحله پرداخت میشود.
|
||||
|
||||
Reject نیز تست شده:
|
||||
- با موفقیت انجام شد.
|
||||
- عنوان/وضعیت به «رد شد» تغییر کرد.
|
||||
- Actionهای Review حذف شدند.
|
||||
|
||||
Request Changes هنوز باید از API و End-to-End تست شود.
|
||||
|
||||
---
|
||||
|
||||
## 3. APIهای Staff Review
|
||||
|
||||
در `routes/api.php` این مسیرها وجود دارند:
|
||||
|
||||
```text
|
||||
GET /api/v1/staff/orders/pending-approval
|
||||
POST /api/v1/staff/orders/{shipment}/request-changes
|
||||
POST /api/v1/staff/orders/{shipment}/approve
|
||||
POST /api/v1/staff/orders/{shipment}/reject
|
||||
```
|
||||
|
||||
این گروه با:
|
||||
|
||||
```php
|
||||
\App\Http\Middleware\StaffApiMiddleware::class
|
||||
```
|
||||
|
||||
محافظت میشود.
|
||||
|
||||
---
|
||||
|
||||
## 4. Authorization
|
||||
|
||||
User از Spatie Permission استفاده میکند.
|
||||
|
||||
Roleهای مهم:
|
||||
- `super_admin`
|
||||
- `admin`
|
||||
- `staff`
|
||||
- `customer`
|
||||
|
||||
تستها:
|
||||
|
||||
Customer با Token معتبر -> `403 Forbidden`
|
||||
|
||||
Super Admin -> دسترسی موفق.
|
||||
|
||||
User شماره 1:
|
||||
- name: مدیر کاظم
|
||||
- role: `super_admin`
|
||||
- Spatie role: `super_admin`
|
||||
|
||||
---
|
||||
|
||||
## 5. Pending Approval API — موفق
|
||||
|
||||
Endpoint:
|
||||
|
||||
```text
|
||||
GET /api/v1/staff/orders/pending-approval
|
||||
```
|
||||
|
||||
با Super Admin و Bearer Token تست شد و:
|
||||
|
||||
```text
|
||||
HTTP/1.1 200 OK
|
||||
```
|
||||
|
||||
برگشت.
|
||||
|
||||
یک Shipment فعلی در پاسخ:
|
||||
|
||||
```text
|
||||
id = 22
|
||||
awb_no = IFN-2026-39337
|
||||
status.value = pending_approval
|
||||
review.state = pending
|
||||
```
|
||||
|
||||
API شامل:
|
||||
- shipment id
|
||||
- AWB
|
||||
- direction/type
|
||||
- status
|
||||
- review
|
||||
- from/to country
|
||||
- user
|
||||
- weight
|
||||
- chargeable_weight
|
||||
- total_fee
|
||||
- created_at
|
||||
- created_at_jalali
|
||||
- pagination
|
||||
|
||||
است.
|
||||
|
||||
---
|
||||
|
||||
## 6. مشکل ShipmentStatus — حل شد
|
||||
|
||||
در `StaffOrderController.php` این import اضافه/اصلاح شده:
|
||||
|
||||
```php
|
||||
use App\Enums\ShipmentStatus;
|
||||
```
|
||||
|
||||
و:
|
||||
|
||||
```php
|
||||
->where('status', ShipmentStatus::PendingApproval)
|
||||
```
|
||||
|
||||
ابتدا خطای:
|
||||
|
||||
```text
|
||||
Class "App\Http\Controllers\Api\ShipmentStatus" not found
|
||||
```
|
||||
|
||||
وجود داشت.
|
||||
|
||||
بعد از اصلاح، Tinker تأیید کرد:
|
||||
|
||||
```php
|
||||
\App\Enums\ShipmentStatus::PendingApproval
|
||||
```
|
||||
|
||||
و:
|
||||
|
||||
```text
|
||||
value = pending_approval
|
||||
```
|
||||
|
||||
پس این مشکل حل شده است.
|
||||
|
||||
---
|
||||
|
||||
## 7. ShipmentStatus.php
|
||||
|
||||
فایل:
|
||||
|
||||
`app\Enums\ShipmentStatus.php`
|
||||
|
||||
Enum شامل statusهای اصلی است:
|
||||
|
||||
```text
|
||||
pending_approval
|
||||
approved
|
||||
pending_payment
|
||||
cancelled
|
||||
processed
|
||||
picked_up
|
||||
in_transit
|
||||
out_for_delivery
|
||||
failed
|
||||
delivered
|
||||
returned
|
||||
archived
|
||||
```
|
||||
|
||||
متدهای مهم:
|
||||
|
||||
```php
|
||||
isApproved()
|
||||
isPendingApproval()
|
||||
canBeApprovedByStaff()
|
||||
canBePaid()
|
||||
```
|
||||
|
||||
انتهای فایل بررسی شد و `canBeApprovedByStaff()` و `canBePaid()` بهدرستی بسته شدهاند.
|
||||
|
||||
---
|
||||
|
||||
## 8. مشکل ShipmentPdfController — حل شد
|
||||
|
||||
`route:list` ابتدا به علت نبود import صحیح برای `ShipmentPdfController` خطا میداد.
|
||||
|
||||
فایل واقعی:
|
||||
|
||||
`app\Http\Controllers\ShipmentPdfController.php`
|
||||
|
||||
Namespace:
|
||||
|
||||
```php
|
||||
namespace App\Http\Controllers;
|
||||
```
|
||||
|
||||
پس import صحیح باید بر اساس همین namespace باشد.
|
||||
|
||||
بعد از اصلاح، این دستور موفق شد:
|
||||
|
||||
```powershell
|
||||
php artisan route:list --path=api/v1/staff
|
||||
```
|
||||
|
||||
و 6 route نشان داده شد:
|
||||
- customers/search
|
||||
- customers/{customer}/financial-status
|
||||
- orders/pending-approval
|
||||
- orders/{shipment}/approve
|
||||
- orders/{shipment}/reject
|
||||
- orders/{shipment}/request-changes
|
||||
|
||||
---
|
||||
|
||||
## 9. مشکل PSR-4 — هنوز حل نشده
|
||||
|
||||
این دستور دو فایل پیدا کرده:
|
||||
|
||||
```powershell
|
||||
Get-ChildItem .\app -Recurse -Filter "StaffApiMiddleware.php" | Select-Object FullName
|
||||
```
|
||||
|
||||
نتیجه:
|
||||
|
||||
```text
|
||||
app\Http\Controllers\StaffApiMiddleware.php
|
||||
app\Http\Middleware\StaffApiMiddleware.php
|
||||
```
|
||||
|
||||
Composer هشدار میدهد:
|
||||
|
||||
```text
|
||||
Class App\Http\Middleware\StaffApiMiddleware located in
|
||||
./app/Http/Controllers/StaffApiMiddleware.php
|
||||
does not comply with psr-4 autoloading standard.
|
||||
```
|
||||
|
||||
بنابراین باید قبل از هر چیز دو فایل را مقایسه کنیم.
|
||||
|
||||
### قدم بعدی دقیق
|
||||
|
||||
اجرا:
|
||||
|
||||
```powershell
|
||||
Get-Content .\app\Http\Controllers\StaffApiMiddleware.php
|
||||
```
|
||||
|
||||
و:
|
||||
|
||||
```powershell
|
||||
Get-Content .\app\Http\Middleware\StaffApiMiddleware.php
|
||||
```
|
||||
|
||||
سپس:
|
||||
|
||||
```powershell
|
||||
Select-String -Path .\app\**\*.php -Pattern "StaffApiMiddleware"
|
||||
```
|
||||
|
||||
هدف:
|
||||
1. مشخص شود کدام فایل Middleware واقعی است.
|
||||
2. بررسی شود فایل Controllers duplicate است یا خیر.
|
||||
3. فقط پس از تأیید، duplicate حذف شود.
|
||||
4. سپس:
|
||||
|
||||
```powershell
|
||||
composer dump-autoload
|
||||
```
|
||||
|
||||
و هشدار PSR-4 دیگر نباید ظاهر شود.
|
||||
|
||||
---
|
||||
|
||||
## 10. پاکسازیها
|
||||
|
||||
اینها با موفقیت اجرا شدهاند:
|
||||
|
||||
```powershell
|
||||
php artisan optimize:clear
|
||||
composer dump-autoload
|
||||
```
|
||||
|
||||
Composer package discovery و Filament upgrade نیز موفق بودهاند.
|
||||
|
||||
---
|
||||
|
||||
## 11. PowerShell
|
||||
|
||||
نوشتن:
|
||||
|
||||
```text
|
||||
GET /api/v1/staff/orders/pending-approval
|
||||
```
|
||||
|
||||
مستقیم در PowerShell اشتباه است؛ PowerShell آن را command تلقی میکند.
|
||||
|
||||
برای تست HTTP:
|
||||
|
||||
```powershell
|
||||
curl.exe -i `
|
||||
-H "Authorization: Bearer YOUR_TOKEN" `
|
||||
-H "Accept: application/json" `
|
||||
http://127.0.0.1:8000/api/v1/staff/orders/pending-approval
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 12. Token
|
||||
|
||||
یک Token تستی برای Super Admin ساخته و استفاده شد. Token واقعی را در این فایل ثبت نکردهایم.
|
||||
|
||||
برای ادامه، در صورت نیاز Token جدید بساز و Token تستی را credential دائمی تلقی نکن.
|
||||
|
||||
---
|
||||
|
||||
## 13. StaffOrderController
|
||||
|
||||
فایل:
|
||||
|
||||
`app\Http\Controllers\Api\StaffOrderController.php`
|
||||
|
||||
متدهای اصلی:
|
||||
|
||||
```text
|
||||
pendingApproval()
|
||||
requestChanges()
|
||||
approve()
|
||||
reject()
|
||||
formatShipment()
|
||||
toJalali()
|
||||
```
|
||||
|
||||
Business logic Review به:
|
||||
|
||||
```text
|
||||
ShipmentReviewService
|
||||
```
|
||||
|
||||
سپرده شده و نباید منطق اصلی Review را داخل Controller کپی کنیم.
|
||||
|
||||
---
|
||||
|
||||
## 14. تستهای بعدی
|
||||
|
||||
### A — Request Changes
|
||||
|
||||
```text
|
||||
POST /api/v1/staff/orders/{shipment}/request-changes
|
||||
```
|
||||
|
||||
نمونه:
|
||||
|
||||
```json
|
||||
{
|
||||
"reason": "لطفاً اطلاعات گیرنده اصلاح شود.",
|
||||
"notes": "شماره تماس کامل نیست."
|
||||
}
|
||||
```
|
||||
|
||||
انتظار:
|
||||
- `review_state = changes_requested`
|
||||
- ایجاد Review History
|
||||
- سفارش قابل ویرایش/Resubmit باشد.
|
||||
|
||||
### B — Approve API
|
||||
|
||||
```text
|
||||
POST /api/v1/staff/orders/{shipment}/approve
|
||||
```
|
||||
|
||||
انتظار:
|
||||
|
||||
```text
|
||||
review_state = approved
|
||||
status = approved
|
||||
```
|
||||
|
||||
### C — Reject API
|
||||
|
||||
```text
|
||||
POST /api/v1/staff/orders/{shipment}/reject
|
||||
```
|
||||
|
||||
با reason اجباری.
|
||||
|
||||
انتظار:
|
||||
|
||||
```text
|
||||
review_state = rejected
|
||||
status = cancelled
|
||||
```
|
||||
|
||||
### D — Customer Resubmit
|
||||
|
||||
پس از Request Changes:
|
||||
- Customer دلیل اصلاح را ببیند.
|
||||
- سفارش را اصلاح کند.
|
||||
- Resubmit کند.
|
||||
- Review State دوباره `pending` شود.
|
||||
- revision جدید ایجاد شود.
|
||||
- AWB تغییر نکند.
|
||||
- Shipment/Packages/Items transactional بهروزرسانی شوند.
|
||||
|
||||
---
|
||||
|
||||
## 15. API Contract
|
||||
|
||||
Laravel منبع canonical Order Detail API است.
|
||||
|
||||
ساختار هدف:
|
||||
|
||||
```text
|
||||
shipment
|
||||
├── status
|
||||
├── review
|
||||
├── sender
|
||||
├── receiver
|
||||
├── packages[]
|
||||
├── items[]
|
||||
├── financial
|
||||
├── documents[]
|
||||
└── tracking_events[]
|
||||
```
|
||||
|
||||
WordPress باید این contract را مصرف کند، نه اینکه روی flattened legacy fields تکیه کند.
|
||||
|
||||
Mismatchهای شناختهشده:
|
||||
|
||||
Laravel:
|
||||
```text
|
||||
sender.*
|
||||
receiver.*
|
||||
```
|
||||
|
||||
WordPress قدیمی:
|
||||
```text
|
||||
sender_name
|
||||
sender_phone
|
||||
receiver_name
|
||||
receiver_phone
|
||||
```
|
||||
|
||||
Tracking:
|
||||
|
||||
Laravel:
|
||||
```text
|
||||
date
|
||||
description
|
||||
location
|
||||
```
|
||||
|
||||
WordPress:
|
||||
```text
|
||||
event_date
|
||||
event_description
|
||||
event_time
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 16. موارد Hardening شناختهشده
|
||||
|
||||
1. `ShipmentStatus::isPaid()` از نظر semantic امن نیست.
|
||||
2. `Shipment::isDelivered()` باید از نظر Enum/string بررسی شود.
|
||||
3. Staff authorization باید صریح و role-aware بماند.
|
||||
4. Sender/receiver API contract باید یکسان شود.
|
||||
5. Tracking event contract باید یکسان شود.
|
||||
6. PDF token key باید با Bridge token استاندارد هماهنگ شود.
|
||||
7. Commitment Form requirement باید برای Shipment snapshot شود.
|
||||
8. Signed-document upload باید از public storage semantics خارج/harden شود.
|
||||
9. `ShipmentPackage` و `ShipmentItem` در detailed customer response بررسی شوند.
|
||||
10. Payment state نباید در بلندمدت از Shipment status استنتاج شود.
|
||||
11. Preview pricing و committed pricing باید تفکیک شوند.
|
||||
12. Migrationهای تاریخی rewrite نشوند.
|
||||
|
||||
---
|
||||
|
||||
## 17. Payment Architecture
|
||||
|
||||
هدف نهایی:
|
||||
|
||||
```text
|
||||
Shipment Operational Status
|
||||
Review State
|
||||
Payment State
|
||||
```
|
||||
|
||||
سه domain مستقل.
|
||||
|
||||
فعلاً:
|
||||
|
||||
```text
|
||||
Approved -> payment available
|
||||
```
|
||||
|
||||
اما این coupling باید در معماری نهایی حذف/deprecate شود.
|
||||
|
||||
---
|
||||
|
||||
## 18. Commitment Documents
|
||||
|
||||
`CommitmentForm` = template
|
||||
|
||||
`ShipmentCommitmentForm` = requirement/instance برای Shipment
|
||||
|
||||
برای Client فعلی:
|
||||
- physical delivery فرآیند اصلی است.
|
||||
- online upload اختیاری است.
|
||||
- signed document نباید بدون business policy صریح approval/payment را block کند.
|
||||
|
||||
هدف بعدی: snapshot شدن required documents برای هر Shipment.
|
||||
|
||||
---
|
||||
|
||||
## 19. Finance Boundary
|
||||
|
||||
IFNEX نباید accounting system کامل شود.
|
||||
|
||||
حوزه مالی IFNEX:
|
||||
- wallet
|
||||
- receivable/debt
|
||||
- order financial status
|
||||
- payment transactions
|
||||
- credit/settlement
|
||||
- audit trail
|
||||
|
||||
Accounting عمیق در صورت نیاز باید external integration باشد.
|
||||
|
||||
---
|
||||
|
||||
## 20. End-to-End هدف
|
||||
|
||||
```text
|
||||
Customer creates order
|
||||
↓
|
||||
Pending Approval
|
||||
↓
|
||||
Staff Review
|
||||
┌────┼─────┐
|
||||
↓ ↓ ↓
|
||||
Changes Approve Reject
|
||||
↓
|
||||
Customer Edit
|
||||
↓
|
||||
Resubmit
|
||||
↓
|
||||
Pending Approval
|
||||
↓
|
||||
Approve
|
||||
↓
|
||||
Payment
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 21. ترتیب ادامه کار
|
||||
|
||||
1. مقایسه دو `StaffApiMiddleware.php`.
|
||||
2. رفع duplicate/PSR-4 warning.
|
||||
3. `composer dump-autoload`.
|
||||
4. `php artisan route:list --path=api/v1/staff`.
|
||||
5. تست Pending Approval مجدد.
|
||||
6. تست Request Changes API.
|
||||
7. تست Approve API.
|
||||
8. تست Reject API.
|
||||
9. بررسی `ShipmentReviewService` و `ShipmentReview`.
|
||||
10. تست Customer Resubmit.
|
||||
11. بررسی Customer Order Detail API.
|
||||
12. هماهنگسازی WordPress Bridge با Laravel canonical contract.
|
||||
13. تست End-to-End کامل.
|
||||
14. سپس سایر Hardeningهای Client Delivery.
|
||||
|
||||
---
|
||||
|
||||
## 22. پیام شروع پیشنهادی برای چت جدید
|
||||
|
||||
```text
|
||||
ما روی پروژه IFNEX-Logistics کار میکنیم.
|
||||
فایل IFNEX_Logistics_Review_Workflow_HANDOFF.md را مبنا قرار بده.
|
||||
|
||||
آخرین وضعیت:
|
||||
GET /api/v1/staff/orders/pending-approval با super_admin موفقاً HTTP 200 میدهد.
|
||||
Approve و Reject در Filament تست شدهاند.
|
||||
Request Changes و Resubmit هنوز باید تست شوند.
|
||||
|
||||
اولین کار:
|
||||
دو فایل زیر را مقایسه کنیم و PSR-4 warning را بدون خراب کردن Middleware واقعی رفع کنیم:
|
||||
|
||||
app\Http\Controllers\StaffApiMiddleware.php
|
||||
app\Http\Middleware\StaffApiMiddleware.php
|
||||
|
||||
بعد APIهای request-changes / approve / reject و customer resubmit را تست کنیم.
|
||||
```
|
||||
Loading…
Reference in New Issue
Block a user