Read-only inventory of all 7 projects (3 reference + 4 target) produced by parallel subagents, every claim cited path:line. No source code changed. - 00-INVENTORY.md consolidated mapping: stack, backend, admin, user apps - PROTECTED.md draft protected list (awaiting user confirmation) - ISSUES.md 26 logged issues (security, money/stock, validation, dead code) - CHANGELOG.md change log scaffold - PROGRESS.md resumable state + Q1-Q5 blocking Phase 1 - _inv-*.md 7 raw per-project inventories (8111 lines) Key finding: the reference is a gold-jewellery B2B/B2C e-commerce system, not a gold bank. Buy/sell, deposit/withdraw, transfer, KYC levels, payment callbacks, cron and websockets do not exist in it, so they cannot be parity gaps. [ref: henza_server, henza_admin, henza_pwa] Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
121 KiB
Inventory — henza_server (reference backend)
Evidence-based inventory. All
path:lineare relative tohenza_server/. Domain note: this codebase is a gold jewelry B2B/B2C e-commerce + wholesale ledger, not a "gold bank". There is no buy/sell order book, no deposit/withdraw, no KYC-level system, no transfer between users. Gold is handled as (a) a live 18-ayar price feed used in product pricing, and (b) a gram-denominated wallet (cashback/loyalty). See §7 for what exists vs. what does not.
1. Stack & versions
| Item | Value | Evidence |
|---|---|---|
| Framework | laravel/framework: ^8.0 |
composer.json:19 |
| PHP | ^7.3 |
composer.json:10 |
| App name/env | APP_NAME, APP_ENV, APP_DEBUG, APP_URL |
config/app.php |
| Autoload PSR-4 | App\ → app/, Rooyesh\Wallet\ → packages/rooyesh/wallet/src/ |
composer.json:41-46 |
| Custom app version | 2.2.0 |
config/version.php:3 |
Key packages (composer.json:9-27)
| Package | Constraint | Line | Purpose |
|---|---|---|---|
apility/laravel-fcm |
^1.4 |
11 | Push (FCM) |
brozot/laravel-fcm |
^1.3 |
13 | Push (FCM, second impl) |
barryvdh/laravel-dompdf |
^0.9.0 |
12 | PDF invoices |
niklasravnsborg/laravel-pdf |
^4.1 |
24 | PDF (mPDF) |
fideloper/proxy |
^4.2 |
14 | Trusted proxies |
fruitcake/laravel-cors |
^2.0 |
15 | CORS |
guzzlehttp/guzzle |
^7.0.1 |
16 | HTTP (SMS/price feeds) |
hekmatinasser/verta |
^2.1 |
17 | Jalali dates |
morilog/jalali |
3.* |
22 | Jalali dates (primary, used in Utility) |
ixudra/curl |
^6.21 |
18 | cURL (payping) |
jgrossi/corcel |
^5.0 |
19 | WordPress DB bridge (config/corcel.php) |
maatwebsite/excel |
^3.1 |
21 | Excel export (TableEngine) |
phpoffice/phpspreadsheet |
* |
23 | Excel |
phpro/soap-client |
^1.4 |
25 | SOAP (legacy Zarinpal) |
laravel/tinker |
^2.0 |
20 | — |
Dev: facade/ignition ^2.3.6, fzaninotto/faker ^1.9.1, mockery/mockery ^1.3.1, nunomaduro/collision ^5.0, phpunit/phpunit ^9.3 (composer.json:29-35).
Local package: packages/rooyesh/wallet — in-repo gold/credit wallet module (see §7).
2. Bootstrap / Middleware / Auth
2.1 Global middleware — app/Http/Kernel.php:17-25 (order as declared)
| # | Class | Line |
|---|---|---|
| — | App\Http\Middleware\TrustHosts |
18 (commented out) |
| 1 | App\Http\Middleware\TrustProxies |
19 |
| 2 | Fruitcake\Cors\HandleCors |
20 |
| 3 | App\Http\Middleware\PreventRequestsDuringMaintenance |
21 |
| 4 | Illuminate\Foundation\Http\Middleware\ValidatePostSize |
22 |
| 5 | App\Http\Middleware\TrimStrings |
23 |
| 6 | Illuminate\Foundation\Http\Middleware\ConvertEmptyStringsToNull |
24 |
2.2 Middleware groups — app/Http/Kernel.php:32-47
| Group | Stack (in order) | Lines |
|---|---|---|
web |
EncryptCookies, AddQueuedCookiesToResponse, StartSession, (AuthenticateSession commented, :37), ShareErrorsFromSession, VerifyCsrfToken, SubstituteBindings |
33-41 |
api |
throttle:api, SubstituteBindings |
43-46 |
Rate limit: Limit::perMinute(500) for the api limiter — app/Providers/RouteServiceProvider.php:76-78.
2.3 Route middleware aliases — app/Http/Kernel.php:56-68
| Alias | Class | Line |
|---|---|---|
auth |
App\Http\Middleware\Authenticate |
57 |
auth.basic |
Illuminate\Auth\Middleware\AuthenticateWithBasicAuth |
58 |
cache.headers |
Illuminate\Http\Middleware\SetCacheHeaders |
59 |
can |
Illuminate\Auth\Middleware\Authorize |
60 |
guest |
App\Http\Middleware\RedirectIfAuthenticated |
61 |
password.confirm |
Illuminate\Auth\Middleware\RequirePassword |
62 |
signed |
Illuminate\Routing\Middleware\ValidateSignature |
63 |
throttle |
Illuminate\Routing\Middleware\ThrottleRequests |
64 |
verified |
Illuminate\Auth\Middleware\EnsureEmailIsVerified |
65 |
version |
App\Http\Middleware\VersionMiddleware |
66 |
create_log |
App\Http\Middleware\CreateLog |
67 |
Custom middleware behavior:
VersionMiddleware— readsconfig('version.version'); if request headerversionpresent and ≠ config, returns{"version": false}—app/Http/Middleware/VersionMiddleware.php:19-33.CreateLog— writes aRequestLogrow (customer_id fromauth()->id(), ip, data, user_agent, route, method) on every request in the group —app/Http/Middleware/CreateLog.php:18-30. Note bug:'device',is a positional value, not a key (:23).Authenticate::redirectTo()—abort(401,'no authorised')instead of redirect —app/Http/Middleware/Authenticate.php:15-21.
2.4 Route file prefixes/middleware — app/Providers/RouteServiceProvider.php:41-66
| File | Prefix | Group middleware | Lines |
|---|---|---|---|
routes/api.php |
api |
api |
43-46 |
routes/web.php |
(none) | web |
48-50 |
routes/admin.php |
admin |
api |
52-55 |
routes/site.php |
site |
api |
57-60 |
routes/customer.php |
cu |
api |
62-65 |
HOME = '/home' (:20). $namespace is commented out (:29) so string-controller routes use FQCN strings.
2.5 Auth guards & providers — config/auth.php
| Guard | Driver | Provider | hash | Line |
|---|---|---|---|---|
web |
session | users |
— | 39-42 |
api (default) |
token | users |
false |
44-48 |
api-customer |
token | customers |
false |
50-54 |
api-singleCustomer |
token | singleCustomers |
false |
56-60 |
Defaults: guard api, passwords users (:16-19).
| Provider | Driver | Model | Line |
|---|---|---|---|
users |
eloquent | App\Models\User |
81-84 |
customers |
eloquent | App\Models\Customer |
85-88 |
singleCustomers |
eloquent | App\Models\SingleCustomer |
89-92 |
Password resets: table password_resets, expire 60, throttle 60 (:115-122). password_timeout: 10800 (:135).
Three-actor model: User = staff/admin (guard api), Customer = wholesale/major shopkeeper (guard api-customer), SingleCustomer = retail web customer, table login (guard api-singleCustomer).
3. Routes (exhaustive)
namecolumn: no route is given a->name()anywhere in any route file. Resource routes get Laravel's implicit names (cat.index, …) which are listed. Middleware column = group middleware from RouteServiceProvider + any explicit route middleware.
3.1 routes/admin.php — prefix admin, middleware api
⚠️ The entire file's auth wrapper Route::middleware('auth:api')->group(...) is COMMENTED OUT at routes/admin.php:12 and :264. Every admin route below is unauthenticated.
| METHOD | path | name | controller@method | middleware/guards | line |
|---|---|---|---|---|---|
| POST | admin/product/create |
— | Adm\ProductController@store |
api | 14 |
| GET | admin/product/show/{id} |
— | Adm\ProductController@show |
api | 15 |
| PUT | admin/product/update/{id} |
— | Adm\ProductController@update |
api | 16 |
| POST | admin/product/test |
— | Adm\ProductController@testSearch |
api | 17 |
| POST | admin/product/report |
— | Adm\ProductController@report |
api | 18 |
| GET | admin/product/color |
— | Adm\ProductController@color |
api | 19 |
| POST | admin/product/variant |
— | Adm\ProductController@getProductsVaraints |
api | 20 |
| GET | admin/product/offer/{product_id} |
— | Adm\ProductController@changeOffer |
api | 21 |
| GET | admin/product/exist/{product_id} |
— | Adm\ProductController@changeIsExist |
api | 22 |
| GET | admin/product/warranty/{product_id} |
— | Adm\ProductController@changeHasWarranty |
api | 23 |
| GET | admin/dashboard/all |
— | Adm\DashboardController@getAll |
api | 26 |
| GET | admin/dashboard/change |
— | Adm\DashboardController@change |
api | 27 |
| GET | admin/dashboard/info |
— | Adm\DashboardController@info |
api | 28 |
| GET | admin/dashboard/link |
— | Adm\DashboardController@link |
api | 29 |
| POST | admin/admin-login |
— | Adm\AdminController@login |
api | 33 |
| POST | admin/products |
— | Adm\AdminController@getProducts |
api | 34 |
| POST | admin/single-customer |
— | Adm\AdminController@getSingleCustomer |
api | 35 |
| GET | admin/category |
— | Adm\AdminController@queryCategory |
api | 36 |
| GET | admin/get-analytics |
— | Adm\AdminController@getAnalytics |
api | 37 |
| GET | admin/get-analytics-tak |
— | Adm\AdminController@getAnalyticsTak |
api | 38 |
| POST | admin/product |
— | Adm\AdminController@addProduct |
api | 39 |
| POST | admin/add/variant |
— | Adm\AdminController@addVariant |
api | 40 |
| GET | admin/get/variant |
— | Adm\AdminController@getVariant |
api | 41 |
| POST | admin/get/variants |
— | Adm\AdminController@getVariants |
api | 42 |
| GET | admin/config/statics |
— | Adm\AdminController@getConfigStatics |
api | 43 |
| GET | admin/product/{id} |
— | Adm\AdminController@getProduct |
api | 44 |
| POST | admin/delete/product/{id} |
— | Adm\AdminController@deleteProduct |
api | 45 |
| POST | admin/category |
— | Adm\AdminController@getCategory |
api | 46 |
| POST | admin/add/category |
— | Adm\AdminController@AddCategory |
api | 47 |
| GET | admin/category/{id} |
— | Adm\AdminController@getOneCategory |
api | 48 |
| GET | admin/havale/list |
— | Adm\AdminController@getHavaleList |
api | 49 |
| DELETE | admin/category/{id} |
— | Adm\AdminController@deleteCategory |
api | 50 |
| GET | admin/price |
— | Closure → WebServiceGold::getAllPrice() |
api | 51-53 |
| POST | admin/change/percent |
— | Adm\AdminController@changePercent |
api | 54 |
| POST | admin/change/percent/count |
— | Adm\AdminController@countProductForPercent |
api | 55 |
| POST | admin/change/all |
— | Adm\AdminController@changeAll |
api | 56 |
| POST | admin/single/order-sts/edit |
— | Adm\AdminController@orderStsSingle |
api | 59 |
| POST | admin/single-order |
— | Adm\AdminController@getSingleOrders |
api | 60 |
| POST | admin/order |
— | Adm\OrderController@store |
api | 61 |
| PUT | admin/order/{id} |
— | Adm\OrderController@update |
api | 62 |
| GET | admin/order/type |
— | Adm\OrderController@getType |
api | 63 |
| GET | admin/order/pdf/{id} |
— | Customer\OrderController@generateReportOrder |
api | 64 |
| POST | admin/cat |
— | Adm\CategoryController@index |
api | 70 |
| GET | admin/cat |
cat.index |
Adm\CategoryController@index |
api | 71 (resource) |
| GET | admin/cat/create |
cat.create |
Adm\CategoryController@create |
api | 71 |
| POST | admin/cat |
cat.store |
Adm\CategoryController@store |
api | 71 |
| GET | admin/cat/{cat} |
cat.show |
Adm\CategoryController@show |
api | 71 |
| GET | admin/cat/{cat}/edit |
cat.edit |
Adm\CategoryController@edit |
api | 71 |
| PUT/PATCH | admin/cat/{cat} |
cat.update |
Adm\CategoryController@update |
api | 71 |
| DELETE | admin/cat/{cat} |
cat.destroy |
Adm\CategoryController@destroy |
api | 71 |
| POST | admin/major/order/table |
— | Adm\MajorOrderController@index |
api | 78 |
| GET | admin/major/order |
major/order.index |
Adm\MajorOrderController@index |
api | 79 (resource) |
| GET | admin/major/order/create |
major/order.create |
Adm\MajorOrderController@create |
api | 79 |
| POST | admin/major/order |
major/order.store |
Adm\MajorOrderController@store |
api | 79 |
| GET | admin/major/order/{order} |
major/order.show |
Adm\MajorOrderController@show |
api | 79 |
| GET | admin/major/order/{order}/edit |
major/order.edit |
Adm\MajorOrderController@edit |
api | 79 |
| PUT/PATCH | admin/major/order/{order} |
major/order.update |
Adm\MajorOrderController@update |
api | 79 |
| DELETE | admin/major/order/{order} |
major/order.destroy |
Adm\MajorOrderController@destroy |
api | 79 |
| DELETE | admin/major/order_item/{id} |
— | Adm\MajorOrderController@deleteOrderItem |
api | 80 |
| POST | admin/order-tamin |
— | Adm\MajorOrderController@getTaminOrders |
api | 81 |
| POST | admin/order-sts/edit |
— | Adm\MajorOrderController@orderSts |
api | 82 |
| POST | admin/order-item/edit |
— | Adm\MajorOrderController@orderItemEdit |
api | 83 |
| POST | admin/delete-order |
— | Adm\MajorOrderController@deleteOrder |
api | 84 |
| POST | admin/brand/create |
— | Adm\BrandController@store |
api | 88 |
| GET | admin/brand |
— | Adm\BrandController@index |
api | 89 |
| PUT | admin/brand/{id} |
— | Adm\BrandController@update |
api | 90 |
| DELETE | admin/brand/{id} |
— | Adm\BrandController@destroy |
api | 91 |
| POST | admin/report/order_item |
— | Adm\ReportController@getOrderItemWithDetails |
api | 96 |
| POST | admin/major/table |
— | Adm\MajorCustomerController@index |
api | 100 |
| GET | admin/major/dashboard/{id} |
— | Adm\MajorCustomerController@dashboard |
api | 101 |
| POST | admin/major/order |
— | Adm\MajorCustomerController@order |
api | 102 (shadowed by resource at :79) |
| POST | admin/major/cash |
— | Adm\MajorCustomerController@cash |
api | 103 |
| POST | admin/major/customer |
— | Adm\MajorCustomerController@shopkeeper |
api | 104 |
| POST | admin/major/sms |
— | Adm\MajorCustomerController@indexSms |
api | 105 |
| POST | admin/major/verify |
— | Adm\MajorCustomerController@verifyRegister |
api | 106 |
| POST | admin/major/archive/table |
— | Adm\MajorCustomerController@indexArchive |
api | 107 |
| POST | admin/major/verify/table |
— | Adm\MajorCustomerController@indexVerify |
api | 108 |
| GET | admin/major/archive/{customer_id} |
— | Adm\MajorCustomerController@archive |
api | 109 |
| GET | admin/major/list_type |
— | Adm\MajorCustomerController@listTypeCustomer |
api | 110 |
| POST | admin/reagent |
— | Adm\AdminController@getReagent |
api | 113 |
| POST | admin/banker |
— | Adm\AdminController@getBanker |
api | 114 |
| POST | admin/shopkeeper |
— | Adm\AdminController@getShopkeeper |
api | 115 |
| POST | admin/customer/toggle-sts |
— | Adm\AdminController@customerToggleSts |
api | 116 |
| POST | admin/customer/toggle-active |
— | Adm\AdminController@customerToggleActive |
api | 117 |
| GET | admin/customer/{id} |
— | Adm\AdminController@getCustomerById |
api | 118 |
| POST | admin/customer |
— | Adm\AdminController@getCustomer |
api | 119 |
| GET | admin/query/customer |
— | Adm\AdminController@queryCustomer |
api | 120 |
| GET | admin/query/reagent |
— | Adm\AdminController@queryReagent |
api | 121 |
| POST | admin/major/promotion/table |
— | Adm\PromotionController@index |
api | 125 |
| PUT | admin/autopromotion |
— | Adm\PromotionController@updateAutoPromotion |
api | 126 |
| GET | admin/autopromotion |
— | Adm\PromotionController@getAutoPromotion |
api | 127 |
| POST | admin/brand |
— | Adm\PromotionController@getBrand |
api | 128 |
| GET | admin/major/promotion |
major/promotion.index |
Adm\PromotionController@index |
api | 129 (resource) |
| GET | admin/major/promotion/create |
major/promotion.create |
Adm\PromotionController@create |
api | 129 |
| POST | admin/major/promotion |
major/promotion.store |
Adm\PromotionController@store |
api | 129 |
| GET | admin/major/promotion/{promotion} |
major/promotion.show |
Adm\PromotionController@show |
api | 129 |
| GET | admin/major/promotion/{promotion}/edit |
major/promotion.edit |
Adm\PromotionController@edit |
api | 129 |
| PUT/PATCH | admin/major/promotion/{promotion} |
major/promotion.update |
Adm\PromotionController@update |
api | 129 |
| DELETE | admin/major/promotion/{promotion} |
major/promotion.destroy |
Adm\PromotionController@destroy |
api | 129 |
| GET | admin/ignore |
ignore.index |
Adm\IgnoreController@index |
api | 132 (resource) |
| GET | admin/ignore/create |
ignore.create |
Adm\IgnoreController@create (not defined) |
api | 132 |
| POST | admin/ignore |
ignore.store |
Adm\IgnoreController@store |
api | 132 |
| GET | admin/ignore/{ignore} |
ignore.show |
Adm\IgnoreController@show |
api | 132 |
| GET | admin/ignore/{ignore}/edit |
ignore.edit |
Adm\IgnoreController@edit (not defined) |
api | 132 |
| PUT/PATCH | admin/ignore/{ignore} |
ignore.update |
Adm\IgnoreController@update (not defined) |
api | 132 |
| DELETE | admin/ignore/{ignore} |
ignore.destroy |
Adm\IgnoreController@destroy($type) |
api | 132 |
| POST | admin/cash/table |
— | Adm\CashController@index |
api | 137 |
| GET | admin/cash |
cash.index |
Adm\CashController@index |
api | 138 (resource) |
| GET | admin/cash/create |
cash.create |
Adm\CashController@create |
api | 138 |
| POST | admin/cash |
cash.store |
Adm\CashController@store |
api | 138 |
| GET | admin/cash/{cash} |
cash.show |
Adm\CashController@show |
api | 138 |
| GET | admin/cash/{cash}/edit |
cash.edit |
Adm\CashController@edit |
api | 138 |
| PUT/PATCH | admin/cash/{cash} |
cash.update |
Adm\CashController@update |
api | 138 |
| DELETE | admin/cash/{cash} |
cash.destroy |
Adm\CashController@destroy |
api | 138 |
| POST | admin/cash/confirem/{id} |
— | Adm\CashController@toggleConfiremCash |
api | 139 |
| POST | admin/file/create |
— | Adm\FileController@storeWithoutData |
api | 145 |
| PUT | admin/file/update/{file_id} |
— | Adm\FileController@updateBody |
api | 146 |
| POST | admin/comment/table |
— | Adm\CommentController@index |
api | 150 |
| GET | admin/comment |
comment.index |
Adm\CommentController@index |
api | 151 (resource) |
| GET | admin/comment/create |
comment.create |
Adm\CommentController@create |
api | 151 |
| POST | admin/comment |
comment.store |
Adm\CommentController@store |
api | 151 |
| GET | admin/comment/{comment} |
comment.show |
Adm\CommentController@show |
api | 151 |
| GET | admin/comment/{comment}/edit |
comment.edit |
Adm\CommentController@edit |
api | 151 |
| PUT/PATCH | admin/comment/{comment} |
comment.update |
Adm\CommentController@update |
api | 151 |
| DELETE | admin/comment/{comment} |
comment.destroy |
Adm\CommentController@destroy |
api | 151 |
| POST | admin/comment/sts |
— | Adm\CommentController@changeStatus |
api | 152 |
| GET | admin/const |
const.index |
Adm\ConstController@index (not defined) |
api | 155 (resource) |
| GET | admin/const/create |
const.create |
Adm\ConstController@create (not defined) |
api | 155 |
| POST | admin/const |
const.store |
Adm\ConstController@store |
api | 155 |
| GET | admin/const/{const} |
const.show |
Adm\ConstController@show |
api | 155 |
| GET | admin/const/{const}/edit |
const.edit |
Adm\ConstController@edit (not defined) |
api | 155 |
| PUT/PATCH | admin/const/{const} |
const.update |
Adm\ConstController@update |
api | 155 |
| DELETE | admin/const/{const} |
const.destroy |
Adm\ConstController@destroy |
api | 155 |
| DELETE | admin/const/by-id/{id} |
— | Adm\ConstController@deleteById |
api | 156 |
| POST | admin/roles |
— | Adm\PermissionController@store |
api | 160 |
| POST | admin/roles/create |
— | Adm\PermissionController@create |
api | 161 |
| DELETE | admin/roles/{ut}/{rid} |
— | Adm\PermissionController@destroy |
api | 162 |
| GET | admin/roles/{ut}/{rid} |
— | Adm\PermissionController@has |
api | 163 |
| GET | admin/roles |
— | Adm\PermissionController@get |
api | 164 |
| GET | admin/roles/{id} |
— | Adm\PermissionController@getByUt |
api | 165 |
| GET | admin/cities |
cities.index |
Adm\CitiesController@index (not defined) |
api | 168 (resource) |
| GET | admin/cities/create |
cities.create |
Adm\CitiesController@create (not defined) |
api | 168 |
| POST | admin/cities |
cities.store |
Adm\CitiesController@store |
api | 168 |
| GET | admin/cities/{city} |
cities.show |
Adm\CitiesController@show |
api | 168 |
| GET | admin/cities/{city}/edit |
cities.edit |
Adm\CitiesController@edit (not defined) |
api | 168 |
| PUT/PATCH | admin/cities/{city} |
cities.update |
Adm\CitiesController@update |
api | 168 |
| DELETE | admin/cities/{city} |
cities.destroy |
Adm\CitiesController@destroy |
api | 168 |
| POST | admin/cities/list |
— | Adm\CitiesController@list |
api | 169 |
| GET | admin/cities/get-percent/{id} |
— | Adm\CitiesController@getPercent |
api | 170 (shadowed by cities.show) |
| GET | admin/cities/get-percent-aux/{id} |
— | Adm\CitiesController@getPercentAux |
api | 171 (shadowed) |
| POST | admin/customer/create |
— | Adm\AdminController@createCustomer |
api | 175 |
| GET | admin/report/order |
— | Adm\AdminController@generateReportOrder |
api | 176 |
| GET | admin/report/doc |
— | Adm\AdminController@generateReportDocument |
api | 177 |
| GET | admin/users/show |
— | Adm\UserController@showData |
api | 180 |
| POST | admin/users/list |
— | Adm\UserController@index |
api | 181 |
| GET | admin/users |
users.index |
Adm\UserController@index |
api | 182 (resource) |
| GET | admin/users/create |
users.create |
Adm\UserController@create (not defined) |
api | 182 |
| POST | admin/users |
users.store |
Adm\UserController@store |
api | 182 |
| GET | admin/users/{user} |
users.show |
Adm\UserController@show |
api | 182 |
| GET | admin/users/{user}/edit |
users.edit |
Adm\UserController@edit (not defined) |
api | 182 |
| PUT/PATCH | admin/users/{user} |
users.update |
Adm\UserController@update |
api | 182 |
| DELETE | admin/users/{user} |
users.destroy |
Adm\UserController@destroy |
api | 182 |
| POST | admin/wallet/percent |
— | Adm\WalletController@changePercent |
api | 186 |
| POST | admin/wallet/table |
— | Adm\WalletController@index |
api | 187 |
| POST | admin/wallet/charge |
— | Adm\WalletController@charge |
api | 188 |
| POST | admin/wallet/config |
— | Adm\WalletController@setConst |
api | 189 |
| GET | admin/wallet/config |
— | Adm\WalletController@getConfig |
api | 190 |
| GET | admin/wallet/birthday/config |
— | Adm\WalletController@getConfigBirthday |
api | 191 |
| POST | admin/single/order |
— | Adm\SingleCustomerController@indexOrder |
api | 194 |
| POST | admin/single/transaction |
— | Adm\SingleCustomerController@indexTransaction |
api | 195 |
| POST | admin/single/sms |
— | Adm\SingleCustomerController@indexSms |
api | 196 |
| GET | admin/single/wallet/{id} |
— | Adm\SingleCustomerController@getWallet |
api | 197 |
| GET | admin/single/report/{id} |
— | Adm\SingleCustomerController@report |
api | 198 |
| GET | admin/single |
single.index |
Adm\SingleCustomerController@index (not defined) |
api | 199 (resource) |
| GET | admin/single/create |
single.create |
@create (not defined) |
api | 199 |
| POST | admin/single |
single.store |
Adm\SingleCustomerController@store |
api | 199 |
| GET | admin/single/{single} |
single.show |
Adm\SingleCustomerController@show |
api | 199 |
| GET | admin/single/{single}/edit |
single.edit |
@edit (not defined) |
api | 199 |
| PUT/PATCH | admin/single/{single} |
single.update |
Adm\SingleCustomerController@update |
api | 199 |
| DELETE | admin/single/{single} |
single.destroy |
@destroy (only delete($id) exists) |
api | 199 |
| POST | admin/sms/table |
— | Adm\SmsController@index |
api | 202 |
| GET | admin/sms/customer |
— | Adm\SmsController@getCustomer |
api | 203 |
| POST | admin/sms/other |
— | Adm\SmsController@sendSmsToOther |
api | 204 |
| POST | admin/notify/customer |
— | Adm\NotifyController@customer |
api | 207 |
| GET | admin/notify/unread |
— | Adm\NotifyController@getUnreadNotify |
api | 208 |
| GET | admin/notify/read/{id} |
— | Adm\NotifyController@read |
api | 209 |
| POST | admin/notify/table |
— | Adm\NotifyController@index |
api | 210 |
| GET | admin/notify |
notify.index |
Adm\NotifyController@index |
api | 211 (resource) |
| GET | admin/notify/create |
notify.create |
@create (not defined) |
api | 211 |
| POST | admin/notify |
notify.store |
Adm\NotifyController@store |
api | 211 |
| GET | admin/notify/{notify} |
notify.show |
Adm\NotifyController@show |
api | 211 |
| GET | admin/notify/{notify}/edit |
notify.edit |
@edit (not defined) |
api | 211 |
| PUT/PATCH | admin/notify/{notify} |
notify.update |
@update (not defined) |
api | 211 |
| DELETE | admin/notify/{notify} |
notify.destroy |
@destroy (not defined) |
api | 211 |
| POST | admin/log/title |
— | Adm\LogController@queryTitle |
api | 214 |
| POST | admin/log/customer/all |
— | Adm\LogController@queryAllCustomer |
api | 215 |
| POST | admin/log/customer/{id} |
— | Adm\LogController@queryCustomer |
api | 216 |
| GET | admin/log/list/customer |
— | Adm\LogController@listCu |
api | 217 |
| GET | admin/log/ago/{id} |
— | Adm\LogController@ago |
api | 218 |
| POST | admin/fashion/table |
— | Adm\AdminController@getListFashion |
api | 221 |
| POST | admin/branch/table |
— | Adm\BranchController@index |
api | 224 |
| GET | admin/branch/active/{id} |
— | Adm\BranchController@activeBranch |
api | 225 |
| GET | admin/branch/list |
— | Adm\BranchController@listBranch |
api | 226 |
| GET | admin/user/list |
— | Adm\BranchController@listUser |
api | 227 (overridden at :248) |
| POST | admin/branch/product |
— | Adm\BranchController@addProduct |
api | 228 |
| PUT | admin/branch/product/{inventory_id} |
— | Adm\BranchController@updateProduct |
api | 229 |
| GET | admin/branch/product/{inventory_id} |
— | Adm\BranchController@getProduct |
api | 230 |
| DELETE | admin/branch/product/{inventory_id} |
— | Adm\BranchController@deleteProduct |
api | 231 |
| POST | admin/branch/product/table |
— | Adm\BranchController@productTable |
api | 232 |
| GET | admin/branch/dashboard |
— | Adm\BranchController@dashboard |
api | 233 |
| GET | admin/branch/admin/dashboard |
— | Adm\BranchController@adminDashboard |
api | 234 |
| GET | admin/branch |
branch.index |
Adm\BranchController@index |
api | 235 (resource) |
| GET | admin/branch/create |
branch.create |
@create (not defined) |
api | 235 |
| POST | admin/branch |
branch.store |
Adm\BranchController@store |
api | 235 |
| GET | admin/branch/{branch} |
branch.show |
Adm\BranchController@show |
api | 235 |
| GET | admin/branch/{branch}/edit |
branch.edit |
@edit (not defined) |
api | 235 |
| PUT/PATCH | admin/branch/{branch} |
branch.update |
Adm\BranchController@update |
api | 235 |
| DELETE | admin/branch/{branch} |
branch.destroy |
Adm\BranchController@destroy |
api | 235 |
| GET | admin/get-custom-order/{id} |
— | Api\CustomOrderController@getCustomOrder |
api | 238 |
| PUT | admin/custom-order/{id} |
— | Api\CustomOrderController@editCustomOrder |
api | 239 |
| POST | admin/get-custom-orders |
— | Api\CustomOrderController@getCustomOrdersAdmin |
api | 240 |
| POST | admin/create-custom-order |
— | Api\CustomOrderController@creatCustomOrder |
api | 241 |
| POST | admin/workshop/table |
— | Adm\WorkshopController@index |
api | 245 |
| GET | admin/workshop/active/{id} |
— | Adm\WorkshopController@activeWorkshop |
api | 246 |
| GET | admin/workshop/list |
— | Adm\WorkshopController@listWorkshop |
api | 247 |
| GET | admin/user/list |
— | Adm\WorkshopController@listUser |
api | 248 (duplicate path, wins over :227) |
| POST | admin/workshop/product |
— | Adm\WorkshopController@addProduct |
api | 249 |
| PUT | admin/workshop/product/{inventory_id} |
— | Adm\WorkshopController@updateProduct |
api | 250 |
| GET | admin/workshop/product/{inventory_id} |
— | Adm\WorkshopController@getProduct |
api | 251 |
| DELETE | admin/workshop/product/{inventory_id} |
— | Adm\WorkshopController@deleteProduct |
api | 252 |
| POST | admin/workshop/product/table |
— | Adm\WorkshopController@productTable |
api | 253 |
| GET | admin/workshop/dashboard |
— | Adm\WorkshopController@dashboard |
api | 254 |
| GET | admin/workshop/admin/dashboard |
— | Adm\WorkshopController@adminDashboard |
api | 255 |
| GET | admin/workshop |
workshop.index |
Adm\WorkshopController@index |
api | 256 (resource) |
| GET | admin/workshop/create |
workshop.create |
@create (not defined) |
api | 256 |
| POST | admin/workshop |
workshop.store |
Adm\WorkshopController@store |
api | 256 |
| GET | admin/workshop/{workshop} |
workshop.show |
Adm\WorkshopController@show |
api | 256 |
| GET | admin/workshop/{workshop}/edit |
workshop.edit |
@edit (not defined) |
api | 256 |
| PUT/PATCH | admin/workshop/{workshop} |
workshop.update |
Adm\WorkshopController@update |
api | 256 |
| DELETE | admin/workshop/{workshop} |
workshop.destroy |
Adm\WorkshopController@destroy |
api | 256 |
| GET | admin/ciny/list |
— | Adm\CinyController@listCiny |
api | 261 |
| POST | admin/ciny/table |
— | Adm\CinyController@index |
api | 262 |
| GET | admin/ciny |
ciny.index |
Adm\CinyController@index |
api | 263 (resource) |
| GET | admin/ciny/create |
ciny.create |
@create (not defined) |
api | 263 |
| POST | admin/ciny |
ciny.store |
Adm\CinyController@store |
api | 263 |
| GET | admin/ciny/{ciny} |
ciny.show |
Adm\CinyController@show |
api | 263 |
| GET | admin/ciny/{ciny}/edit |
ciny.edit |
@edit (not defined) |
api | 263 |
| PUT/PATCH | admin/ciny/{ciny} |
ciny.update |
Adm\CinyController@update |
api | 263 |
| DELETE | admin/ciny/{ciny} |
ciny.destroy |
Adm\CinyController@destroy |
api | 263 |
admin.php total: 216 registered routes (77 explicit + 139 from 14 Route::resource declarations... see count table §3.6).
3.2 routes/api.php — prefix api, middleware api
Public (no auth):
| METHOD | path | name | controller@method | middleware/guards | line |
|---|---|---|---|---|---|
| GET | api/user |
— | Closure → $request->user() |
api + auth:api |
31-33 |
| POST | api/check/version |
— | Api\ApiMobileController@checkVersion |
api | 37 |
| POST | api/login |
— | Api\ApiMobileController@login |
api | 38 |
| POST | api/user-auth |
— | Api\ApiMobileController@userAuth |
api | 39 |
| POST | api/user-verfiy |
— | Api\ApiMobileController@userVerfiy |
api | 40 |
| POST | api/sms |
— | Api\ApiMobileController@sms (method not defined) |
api | 41 |
| GET | api/sms |
— | Api\ApiMobileController@sendSms (not defined) |
api | 42 |
| GET | api/report/order |
— | Adm\AdminController@generateReportOrder |
api | 43 |
| GET | api/report/doc |
— | Adm\AdminController@generateReportDocument |
api | 44 |
| POST | api/customer/create |
— | Adm\AdminController@createCustomer |
api | 45 |
| POST | api/product/luxe |
— | Api\ApiMobileController@getLuxeProduct |
api | 46 |
| GET | api/price |
— | Api\ApiMobileController@PriceFromWebService |
api | 47 |
| POST | api/front |
— | Api\ApiMobileController@front |
api | 49 |
| GET | api/config |
— | Api\ApiMobileController@getConfig |
api | 50 |
| GET | api/product/{id} |
— | Api\ApiMobileController@getProduct |
api | 51 |
| POST | api/get-products |
— | Api\ApiMobileController@getProducts |
api | 52 |
| GET | api/ciny/{collection_id} |
— | Api\ApiMobileController@getCinyByCollectionId |
api | 53 |
| POST | api/get-products/test |
— | Api\ApiMobileController@getProductsTest (not defined) |
api | 54 |
| POST | api/log/create/{title} |
— | Api\LogController@create |
api | 57 |
| GET | api/log/update/{id} |
— | Api\LogController@update |
api | 58 |
| POST | api/major/register |
— | Major\CustomerController@register |
api | 61 |
Authenticated group — Route::middleware('auth:api-customer') (routes/api.php:64-117); guard = api-customer → Customer model:
| METHOD | path | name | controller@method | middleware/guards | line |
|---|---|---|---|---|---|
| GET | api/get-custom-order/{id} |
— | Api\CustomOrderController@getCustomOrder |
api + auth:api-customer |
68 |
| GET | api/get-custom-orders |
— | Api\CustomOrderController@getCustomOrders |
api + auth:api-customer |
69 |
| POST | api/create-custom-order |
— | Api\CustomOrderController@creatCustomOrder |
api + auth:api-customer |
70 |
| POST | api/update-custom-order/{id} |
— | Api\CustomOrderController@updateCustomOrder |
api + auth:api-customer |
71 |
| POST | api/set-order |
— | Api\ApiMobileController@setOrder |
api + auth:api-customer |
74 |
| POST | api/product |
— | Api\ApiMobileController@setProduct |
api + auth:api-customer |
75 |
| POST | api/me-data |
— | Api\ApiMobileController@me |
api + auth:api-customer |
76 |
| POST | api/get-notify |
— | Api\ApiMobileController@getNotify |
api + auth:api-customer |
77 |
| GET | api/notify/count |
— | Api\ApiMobileController@getCountNotify |
api + auth:api-customer |
78 |
| POST | api/get-orders |
— | Api\ApiMobileController@myOrder |
api + auth:api-customer |
79 |
| POST | api/get-my-findoc |
— | Api\ApiMobileController@myFindoc |
api + auth:api-customer |
80 |
| POST | api/update-profile |
— | Api\ApiMobileController@updateProfile |
api + auth:api-customer |
81 |
| POST | api/set-findoc |
— | Api\ApiMobileController@setFindoc |
api + auth:api-customer |
82 |
| POST | api/my-child |
— | Api\ApiMobileController@myChild |
api + auth:api-customer |
83 |
| POST | api/add-to-fav |
— | Api\ApiMobileController@toggleFavorite |
api + auth:api-customer |
84 |
| POST | api/get-favorites |
— | Api\ApiMobileController@getFavorites |
api + auth:api-customer |
85 |
| POST | api/tokenmobile |
— | Api\ApiMobileController@updateTokenMobile |
api + auth:api-customer |
86 |
| GET | api/promotion |
— | Api\ApiMobileController@getPromotion |
api + auth:api-customer |
87 |
| GET | api/ignore |
— | Api\ApiMobileController@getIgnore |
api + auth:api-customer |
88 |
| POST | api/order/child |
— | Api\ApiMobileController@getChildOrder |
api + auth:api-customer |
89 |
| PUT | api/order/child/{id} |
— | Api\ApiMobileController@updateChildOrder |
api + auth:api-customer |
90 |
| PUT | api/notify/read/{id} |
— | Api\ApiMobileController@readNotify |
api + auth:api-customer |
91 |
| POST | api/file/create |
— | Adm\FileController@storeWithoutData |
api + auth:api-customer |
95 |
| POST | api/customer/update |
— | Adm\AdminController@updateCustomer |
api + auth:api-customer |
98 |
| POST | api/customer/toggle-active |
— | Adm\AdminController@customerToggleActive |
api + auth:api-customer |
99 |
| POST | api/customer/toggle-sts |
— | Adm\AdminController@customerToggleSts |
api + auth:api-customer |
100 |
| POST | api/hesab_detail/table |
— | Api\ApiMobileController@hesabDetail |
api + auth:api-customer |
103 |
| POST | api/moshtarian |
— | Api\ApiMobileController@moshtarian |
api + auth:api-customer |
104 |
| GET | api/tahesab/me |
— | Customer\TahesabController@mandeh |
api + auth:api-customer |
108 |
| GET|POST | api/fin_tahesab/table |
— | Customer\TahesabController@index |
api + auth:api-customer |
109 |
| GET | api/fin_tahesab/detail/{id} |
— | Customer\TahesabController@detail |
api + auth:api-customer |
110 |
| GET | api/fin_tahesab/my_detail/{offset} |
— | Customer\TahesabController@my_detail |
api + auth:api-customer |
111 |
| POST | api/major/complete |
— | Major\CustomerController@complete |
api + auth:api-customer |
114 |
Public (after group):
| METHOD | path | name | controller@method | middleware/guards | line |
|---|---|---|---|---|---|
| POST | api/sms/batch |
— | Adm\SmsController@batch |
api | 122 |
| POST | api/sms/batch/test |
— | Adm\SmsController@testNet |
api | 123 |
| GET | api/send/all |
— | Closure — mass-SMS to ALL customers | api | 126-180 |
| POST | api/test |
— | Closure → "this is true" |
api | 184-220 |
| GET | api/cities |
cities.index |
Adm\CitiesController@index (not defined) |
api | 223 (resource) |
| GET | api/cities/create |
cities.create |
@create (not defined) |
api | 223 |
| POST | api/cities |
cities.store |
Adm\CitiesController@store |
api | 223 |
| GET | api/cities/{city} |
cities.show |
Adm\CitiesController@show |
api | 223 |
| GET | api/cities/{city}/edit |
cities.edit |
@edit (not defined) |
api | 223 |
| PUT/PATCH | api/cities/{city} |
cities.update |
Adm\CitiesController@update |
api | 223 |
| DELETE | api/cities/{city} |
cities.destroy |
Adm\CitiesController@destroy |
api | 223 |
| POST | api/cities/list |
— | Adm\CitiesController@list |
api | 224 |
| GET | api/cities/get-percent/{id} |
— | Adm\CitiesController@getPercent |
api | 225 (shadowed) |
| GET | api/cities/get-percent-aux/{id} |
— | Adm\CitiesController@getPercentAux |
api | 226 (shadowed) |
| POST | api/web/auth |
— | WebApp\AuthController@userAuth |
api | 229 |
| GET | api/testt |
— | Customer\TahesabController@test |
api | 235 |
Duplicate name collision:
cities.*resource names are registered in BOTHroutes/admin.php:168androutes/api.php:223. Laravel 8 keeps the first registration for name lookup;api.phploads first (RouteServiceProvider:43), socities.*names resolve to/api/cities/*.
3.3 routes/customer.php — prefix cu, middleware api
Whole file wrapped in Route::middleware('create_log') (routes/customer.php:3).
| METHOD | path | name | controller@method | middleware/guards | line |
|---|---|---|---|---|---|
| POST | cu/register |
— | Api\SingleCustomerController@register |
api, create_log |
5 |
| POST | cu/login |
— | Api\SingleCustomerController@login |
api, create_log |
6 |
| POST | cu/verfiy/token |
— | Api\SingleCustomerController@verfiy |
api, create_log |
7 |
| GET | cu/order/pdf/{id} |
— | Customer\OrderController@generateReportOrder |
api, create_log |
8 |
Inner group ['middleware' => ['auth:api-singleCustomer']] (:10-46) — guard api-singleCustomer → SingleCustomer:
| METHOD | path | name | controller@method | middleware/guards | line |
|---|---|---|---|---|---|
| POST | cu/transaction |
— | Api\SingleCustomerController@getTransaction |
api, create_log, auth:api-singleCustomer |
11 |
| POST | cu/update-profile |
— | Api\SingleCustomerController@updateProfile (not defined) |
″ | 12 |
| GET | cu/get-user |
— | Api\SingleCustomerController@getUserInfo |
″ | 13 |
| GET | cu/comment |
comment.index |
Customer\CommentController@index |
″ | 15 (resource) |
| GET | cu/comment/create |
comment.create |
Customer\CommentController@create |
″ | 15 |
| POST | cu/comment |
comment.store |
Customer\CommentController@store |
″ | 15 |
| GET | cu/comment/{comment} |
comment.show |
Customer\CommentController@show($product_id) |
″ | 15 |
| GET | cu/comment/{comment}/edit |
comment.edit |
Customer\CommentController@edit |
″ | 15 |
| PUT/PATCH | cu/comment/{comment} |
comment.update |
Customer\CommentController@update |
″ | 15 |
| DELETE | cu/comment/{comment} |
comment.destroy |
Customer\CommentController@destroy |
″ | 15 |
| GET|POST | cu/fin_tahesab/table |
— | Customer\TahesabController@index |
″ | 18 |
| GET | cu/fin_tahesab/detail/{id} |
— | Customer\TahesabController@detail |
″ | 19 |
| GET | cu/fin_tahesab/my_detail/{offset} |
— | Customer\TahesabController@my_detail |
″ | 20 |
| GET | cu/fin_tahesab/mandeh |
— | Customer\TahesabController@mandeh |
″ | 21 |
| POST | cu/order/table |
— | Customer\OrderController@index |
″ | 23 |
| GET | cu/order/report |
— | Customer\OrderController@report |
″ | 24 |
| GET | cu/order/promotion |
— | Customer\OrderController@getPromotion |
″ | 25 |
| GET | cu/order |
order.index |
Customer\OrderController@index |
″ | 26 (resource) |
| GET | cu/order/create |
order.create |
Customer\OrderController@create |
″ | 26 |
| POST | cu/order |
order.store |
Customer\OrderController@store |
″ | 26 |
| GET | cu/order/{order} |
order.show |
Customer\OrderController@show |
″ | 26 |
| GET | cu/order/{order}/edit |
order.edit |
Customer\OrderController@edit |
″ | 26 |
| PUT/PATCH | cu/order/{order} |
order.update |
Customer\OrderController@update |
″ | 26 |
| DELETE | cu/order/{order} |
order.destroy |
Customer\OrderController@destroy |
″ | 26 |
| GET | cu/fav |
fav.index |
Customer\FavController@index |
″ | 29 (resource) |
| GET | cu/fav/create |
fav.create |
Customer\FavController@create |
″ | 29 |
| POST | cu/fav |
fav.store |
Customer\FavController@store |
″ | 29 |
| GET | cu/fav/{fav} |
fav.show |
Customer\FavController@show |
″ | 29 |
| GET | cu/fav/{fav}/edit |
fav.edit |
Customer\FavController@edit |
″ | 29 |
| PUT/PATCH | cu/fav/{fav} |
fav.update |
Customer\FavController@update |
″ | 29 |
| DELETE | cu/fav/{fav} |
fav.destroy |
Customer\FavController@destroy |
″ | 29 |
| GET | cu/address |
address.index |
Customer\AddressController@index |
″ | 32 (resource) |
| GET | cu/address/create |
address.create |
@create (not defined) |
″ | 32 |
| POST | cu/address |
address.store |
Customer\AddressController@store |
″ | 32 |
| GET | cu/address/{address} |
address.show |
@show (not defined) |
″ | 32 |
| GET | cu/address/{address}/edit |
address.edit |
@edit (not defined) |
″ | 32 |
| PUT/PATCH | cu/address/{address} |
address.update |
Customer\AddressController@update |
″ | 32 |
| DELETE | cu/address/{address} |
address.destroy |
Customer\AddressController@destroy |
″ | 32 |
| POST | cu/set-default |
— | Customer\AddressController@setDefaultAddress |
″ | 33 |
| POST | cu/transaction/gateway |
— | Customer\TransactionController@gateway |
″ | 36 |
| POST | cu/product/variant |
— | Customer\ProductController@getVariant |
″ | 39 |
| GET | cu/customer/wallet |
— | Customer\CustomerController@getWallet |
″ | 42 |
| POST | cu/customer/wallet/transaction |
— | Customer\CustomerController@detailWallet |
″ | 43 |
3.4 routes/site.php — prefix site, middleware api
| METHOD | path | name | controller@method | middleware/guards | line |
|---|---|---|---|---|---|
| GET | site/test |
— | Closure → 'this is test' |
api | 4-6 |
| GET | site/get-config |
— | Api\SiteController@config |
api | 8 |
| POST | site/config |
— | Api\SiteController@newConfig |
api | 9 |
| POST | site/products |
— | Api\SiteController@Products |
api | 10 |
| GET | site/get-product |
— | Api\SiteController@getProduct |
api | 11 |
| GET | site/front |
— | Api\SiteController@ّFront (note leading Arabic kasra U+0651 in method name) |
api | 12 |
| GET | site/counter |
— | Api\SiteController@counterInstagram |
api | 13 |
| GET | site/price |
— | Closure → WebServiceGold::getAllPrice() |
api | 14-16 |
| POST | site/get/products |
— | Api\SiteController@getProductsVaraints |
api | 17 |
| POST | site/get/fashion |
— | Api\SiteController@setRequestFashion |
api | 18 |
| GET | site/product/ready |
— | Api\SiteController@readySend |
api | 19 |
| GET | site/te/print/{id} |
— | Closure → DB\Te\TableEngine::viewPrint($id) |
api | 22-24 |
| GET | site/comment/{id} |
— | Customer\CommentController@show |
api | 26 |
| GET | site/app/download |
— | Api\SiteController@downloadApk |
api | 27 |
| GET | site/fix-cat |
— | Closure — one-off category remap, dd()s |
api | 30-65 |
| GET | site/const/{id} |
— | Adm\ConstController@show |
api | 68 |
| GET | site/body/{id} |
— | Site\CollectionController@getBody |
api | 71 |
| POST | site/category/product |
— | Site\CollectionController@products |
api | 72 |
| GET | site/product |
— | Site\SiteController@getProduct |
api + version |
75-78 |
| GET | site/product/random |
— | Api\SiteController@getRandomProduct |
api | 79 |
| GET | site/login/active |
— | Api\SiteController@counterActive |
api | 80 |
| GET | site/landing/page |
— | Api\SiteController@counterLanding |
api | 81 |
| POST | site/test |
— | Site\SiteController@products |
api | 83 |
| GET | site/customer |
— | Site\SiteController@getCustomer |
api | 84 |
| GET | site/tag |
— | Site\SiteController@addTag |
api | 85 |
| GET | site/birthday |
— | Site\SiteController@getBirthday |
api | 86 |
| GET | site/service |
— | Site\SiteController@serviceGold |
api | 87 |
| GET | site/test/tr |
— | Site\SiteController@test123 |
api | 88 |
| GET | site/test/active |
— | Site\SiteController@searchDeactive |
api | 89 |
| GET | site/test/g |
— | Site\SiteController@testG |
api | 90 |
3.5 routes/web.php — no prefix, middleware web
| METHOD | path | name | controller@method | middleware/guards | line |
|---|---|---|---|---|---|
| GET|POST | /fin_tahesab/table |
— | Customer\TahesabController@index |
web | 26 |
| GET | /fin_tahesab/detail/{id} |
— | Customer\TahesabController@detail |
web | 27 |
| GET | /fin_tahesab/my_detail/{offset} |
— | Customer\TahesabController@my_detail |
web | 28 |
| GET | /fin_tahesab/mandeh |
— | Customer\TahesabController@mandeh |
web | 29 |
| GET | / |
— | Closure — scrapes tgju.org and writes gold_price + gold_price_pwa ConfigStatic |
web | 32-124 |
| GET | /login |
— | Closure — Link::set(...) + redirect to https://henzagold.com/app |
web | 127-130 |
| GET | /download |
— | Closure — Link::set(...) + redirect to APK |
web | 131-134 |
| GET | /totalify |
— | Closure — recount category totals, dd()s |
web | 137-152 |
| GET | /confirem/order |
— | Adm\AdminController@confiremOrder |
web | 156 |
| GET | /test2 |
— | Closure — mass-SMS to ALL customers | web | 158-186 |
3.6 Route counts per file
| File | Explicit routes | Route::resource blocks |
Routes from resources (7 each) | Total registered |
|---|---|---|---|---|
routes/admin.php |
117 | 14 | 98 | 215 |
routes/api.php |
63 | 1 | 7 | 70 |
routes/customer.php |
16 | 4 | 28 | 44 |
routes/site.php |
30 | 0 | 0 | 30 |
routes/web.php |
10 | 0 | 0 | 10 |
| TOTAL | 236 | 19 | 133 | 369 |
Resource blocks: admin.php:71,79,129,132,138,151,155,168,182,199,211,235,256,263 (14); api.php:223 (1); customer.php:15,26,29,32 (4).
4. Controllers (app/Http/Controllers, recursive)
24 controllers total (excluding base Controller.php, which is listed separately as it holds shared business logic).
| Controller | Public methods |
|---|---|
Controller.php (base) |
addLimit, convert, createTransactionOrder, createSingleOrderActivity, createSingleCustomerOrders, createSingleCustomerOrderItems, createPromotionForOrder, afterCreateOrder, createTransactionInterface, checkCustomer |
Adm/AdminController.php |
__construct, login, getProducts, queryCategory, getCustomer, getReagent, getBanker, getShopkeeper, getSingleCustomer, updateCustomer, createCustomer, queryCustomer, queryReagent, customerToggleSts, customerToggleActive, confiremOrder, getAnalytics, getAnalyticsTak, addProduct, addVariant, getVariant, getVariants, getConfigStatics, getProduct, deleteProduct, getCustomerById, getCategory, AddCategory, getOneCategory, deleteCategory, getSingleOrders, changePercent, countProductForPercent, generateReportOrder, orderStsSingle, chargeWalletAfterOrder, getHavaleList, changeAll, generateReportDocument, getListFashion |
Adm/BranchController.php |
index, store, show, update, destroy, activeBranch, listBranch, listUser, allocateProduct, addProduct, updateProduct, getProduct, deleteProduct, createInventoryTransaction, productTable, dashboard, adminDashboard |
Adm/BrandController.php |
index, store, update, destroy |
Adm/CashController.php |
index, create, store, show, edit, update, destroy, toggleConfiremCash |
Adm/CategoryController.php |
index |
Adm/CinyController.php |
store, update, destroy, show, listCiny, index |
Adm/CitiesController.php |
store, destroy, show, list, getPercent, getPercentAux, update |
Adm/CommentController.php |
index, create, store, show, edit, update, destroy, changeStatus |
Adm/ConstController.php |
store, destroy, deleteById, show, update |
Adm/DashboardController.php |
getAll, change, info, link |
Adm/FileController.php |
index, store, storeWithoutData, show, update, destroy, updateBody |
Adm/IgnoreController.php |
index, store, show, destroy |
Adm/LogController.php |
queryTitle, queryAllCustomer, queryCustomer, queryForLog, listCu, ago |
Adm/MajorCustomerController.php |
index, dashboard, order, cash, shopkeeper, indexSms, verifyRegister, indexArchive, indexVerify, archive, listTypeCustomer |
Adm/MajorOrderController.php |
index, create, store, show, edit, update, destroy, getTaminOrders, orderSts, orderItemEdit, deleteOrder, deleteOrderItem |
Adm/NotifyController.php |
store, customer, index, getUnreadNotify, show, read |
Adm/OrderController.php |
getType, store, update |
Adm/PermissionController.php |
create, store, destroy, has, get, getByUt |
Adm/ProductController.php |
createImage, store, show, update, testSearch, report, color, getProductsVaraints, changeOffer, changeIsExist, changeHasWarranty |
Adm/PromotionController.php |
index, create, createTablePromotionProduct, createPromotionProduct, store, show, edit, update, destroy, updateAutoPromotion, getAutoPromotion, getBrand |
Adm/ReportController.php |
__construct, collection, registerEvents, headings, getOrderItemWithDetails (implements Maatwebsite Excel export contracts) |
Adm/SingleCustomerController.php |
store, update, delete, show, indexOrder, indexTransaction, indexSms, getWallet, report |
Adm/SmsController.php |
batch, testNet, replaceName, index, getCustomer, sendSmsToOther |
Adm/UserController.php |
store, index, destroy, update, show, showData |
Adm/WalletController.php |
charge, changePercent, index, setConst, getConfig, getConfigBirthday |
Adm/WorkshopController.php |
index, store, show, update, destroy, activeWorkshop, listWorkshop, listUser, allocateProduct, addProduct, updateProduct, getProduct, deleteProduct, createInventoryTransaction, productTable, dashboard, adminDashboard |
Api/ApiMobileController.php |
userAuth, userVerfiy, login, me, setFindoc, updateProfile, getProduct, myChild, myOrder, getNotify, getCountNotify, myFindoc, front, getCinyByCollectionId, getProducts, setProduct, toggleFavorite, getFavorites, updateTokenMobile, getConfig, getPromotion, getIgnore, setOrder, getChildOrder, readNotify, updateChildOrder, getLuxeProduct, checkVersion, PriceFromWebService, hesabDetail, moshtarian, moshtarianFilter |
Api/CustomOrderController.php |
getCustomOrders, getCustomOrdersAdmin, getCustomOrder, editCustomOrder, creatCustomOrder, updateCustomOrder, acceptCustomOrder, deleteCustomOrder |
Api/CustomerController.php |
getVaraints |
Api/LogController.php |
create, update |
Api/SingleCustomerController.php |
register, verfiy, login, getTransaction, getUserInfo |
Api/SiteController.php |
getConfig, config, newConfig, getMenu, getProduct, sendDiscount, products, searchProduct, ّFront, getProductsVaraints, test, counterInstagram, getRandomProduct, counterActive, counterLanding, setRequestFashion, readySend |
Customer/AddressController.php |
index, store, update, destroy, setDefaultAddress |
Customer/CommentController.php |
index, create, store, show, edit, update, destroy |
Customer/CustomerController.php |
getWallet, detailWallet |
Customer/FavController.php |
index, create, store, show, edit, update, destroy |
Customer/OrderController.php |
index, create, store, cancel, show, edit, update, destroy, report, generateReportOrder, getPromotion |
Customer/ProductController.php |
getVariant |
Customer/TahesabController.php |
index, my_detail, detail, mandeh, test |
Customer/TransactionController.php |
gateway |
Major/CustomerController.php |
register, complete, sendSmsToAdmin |
ProductController.php (root) |
index |
Site/CollectionController.php |
getBody, products |
Site/SiteController.php |
products, getCustomer, getProduct, addTag, getBirthday, serviceGold, test123, searchDeactive, testG |
WebApp/AuthController.php |
userAuth |
Controller count: 46 files (45 concrete controllers + base Controller.php).
5. Models (app/Models) — 57 files
Selector(app/DB/Selector.php) is a shared trait providing Jalali accessors (caj,uaj,eaj,daj),sts_str,type_str,sts_verify_step_one_str/two_str,type_show_str,birth_date_j,brj,expire_at_j, plus static lookupsGetSts,GetTypes,GetConfirmed,GetShowType,GetStsVerifyStepOne/Two,selectWithjDate,convertColumns(app/DB/Selector.php:57-206). Duplicated atapp/Te/*andapp/DB/Te/*(TableEngine).
| Model | Table | Key fillable | Casts | Relations | Scopes | Constants / statics | Accessors / mutators |
|---|---|---|---|---|---|---|---|
ApkLog :14 |
apk_log :17 |
ip,version :30 |
— | — | — | $timestamps=false :19; boot() :21 |
— |
Branch :10 |
(branches) | name,address,phone,user_id,is_active :13 |
is_active→bool :20 |
user()→User :23 |
— | — | — |
Category :10 |
category_collection :32 |
title,parent_id_id,priority,image_id,meta,body,icon_id,disabled,type,total,is_master,header,is_active :16 |
disabled,is_active→bool :45 |
parent() hasOne self :51; childs() hasMany self :57; image()→Image :63; icon()→Image :68 |
scopeDesktop :74, scopeMobile :80 |
reloadTotal($id) :86, reloadCategory($cats,$pid) :93 |
$hidden :34 |
Ciny :9 |
cinies |
title,icon_id,collection_id,is_active,description :12 |
:19 |
icon()→Image :22; collection()→Category :26 |
— | — | — |
CinyProduct :9 |
ciny_products |
product_id,ciny_id :12 |
— | product() :16; ciny() :20 |
— | — | — |
City :9 |
cities |
title,parent,level,percent,percent_aux :14 |
— | — | — | — | — |
Collect :9 |
category_collect :14 |
collection_id_id,product_id_id :16 |
— | product() :21; collection() :26 |
— | — | — |
Comment :10 |
(comments) | product_id,comment,reply_to,sts,customer_id :16 |
— | Reply() hasMany self :31; customer()→SingleCustomer :36; product() :42 |
— | $SELECT_CAJ (via Selector) |
— |
ConfigStatic :10 |
config_statics :15 |
key,val :17 |
(val→array commented out :21-23) |
— | — | getValue($key) :25 — throws NotFoundHttpException if 0 rows |
— |
CustomOrder :12 |
(custom_orders) | customer_id,file_id,city_id,weight,color,size,sum,color_stone,color_mina,workshop_id,sts,description :17 |
sts→int, weight/sum→float, deleted_at→datetime :32 |
file()→Image :77; customer() :81; CustomOrderLog() hasMany :85 |
— | $appends=['sts_str_en','sts_str_fa','time_creat_fa','time_update_fa'] :15 |
getTimeCreatFaAttribute :59, getTimeUpdateFaAttribute :63, getStsStrEnAttribute :68, getStsStrFaAttribute :73 |
CustomOrderLog :10 |
— | :15 |
:23 |
order() :37; user() withDefault :43 |
— | $appends :13 |
getTimeCreatFa/UpdateFa :28,:32 |
Customer :13 (Authenticatable, guard api-customer) |
customers |
api_token,address,phone,fname,lname,name,mobile,rnd,ncode,notify_count,total_order,gram_level,percent,input,output,remain,city_id,new_city,rial_remain,rial_output,rial_input,reagent_id,type,open_order,child,sts,token_mobile,send_password,store_name,zone,pasazh_name,active,birth_date,marriage_date,image_id,mcode,sts_verify_step_one,sts_verify_step_two,is_archive,business_license_image_id,shop_image_id,ncode_image_id :18-72 |
is_archive→bool :73 |
reagent() :119; cash() hasMany Major\Cash :124; order() hasMany :130; orderOne() (sts=6) :135; children() hasMany Order by reagent_id :140; city() :145; image() :166; business_license_image() :170; shop_image() :174; ncode_image() :178; workshop() :182 |
scopeSelectify :105, scopeActive :162 |
$hidden=['password','send_password'] :83 |
setPasswordAttribute (Hash) :100; getToAttribute :110; getOrderTitleAttribute :115; getRemainAttribute :150; getGramsSellAttribute :156 |
CustomerTest :13 |
customers_test :18 |
mirror of Customer :20 |
— | same set :94-137 |
scopeSelectify,scopeActive |
$hidden :62 |
same |
Fav :14 |
fav :17 |
customer_id,product_id :23 |
— | product() (active only) :30; customer() :34 |
— | $timestamps=false :22; composite PK (migration) |
— |
Image :8 |
image :13 |
title,position,image,resize*,link,width,height,banner,original_name,ext,body :15 |
— | product() :42; productImage() :46; pi() :53 |
— | $SELECT_FULL |
getFullAttribute :35, getImageAttribute :58 |
InventoryBranch :10 |
— | :13 |
— | allocator_user() :20; branch() :24; product() :28 |
— | — | — |
InventoryTransaction :9 |
— | product_id,product_variant_id,branch_id,allocator_user_id,order_id,type :12 |
— | product() :25; branch() :29; product_variant() :33; allocator_user() :37 |
— | — | — |
Kids :10 |
kids :15 |
:17 |
— | — | — | — | — |
Link :8 |
(links) | :11 |
— | — | — | set($url) :15 — click tracker |
— |
Log :9 |
(logs) | customer_id,time_present,start_at,end_at,ip,title,data,title_fa,product_id :12 |
data→array :23 |
customer() :27; product() :31 |
— | — | — |
Major\Cash :13 |
(cashes) | user_id,customer_id,input,output,remain,rial_input,rial_output,rial_remain,type,sts,title,to,note,ayar,lab,balance,value,price,confirmed,no,proceed_at,account_name,bank_name,recive_date,order_id,ang,original_value,price_per_gram,discount :19 |
— | customer() :86 |
scopeMe :74 |
$TYPES = [9=>سفارش, 1=>آب شده, 2=>حواله, 3=>چک, 4=>پولی] :56; $STS = [-1=>بررسی نشده, 1=>ثبت سند] :63; $CONFIRMED = [1=>تایید شده, 0=>تایید نشده] :68 |
getTimeAttribute :81; getValueAttribute → Utility::round() :91; getConfirmedStrAttribute :96; $appends=['time','confirmed_str'] :51 |
Major\Favorite :9 |
major_favorites :14 |
:16 |
— | — | — | — | — |
Major\Promotion :14 |
major_promotion :21 |
title,description,start_at,end_at,type,type_customer,discount_percent,discount_price,is_active,use_only,show :32 |
is_active,use_only,show→bool :57 |
items() hasMany PromotionItem :86 |
scopeActive :24, scopeWeb :27 |
safeDelete($promotionID) :79 |
getStartAtjAttribute :69, getEndAtjAttribute :74, getItemsAttribute :91; $appends :63 |
Major\PromotionIgnore :11 |
major_promotion_ignores :17 |
:19 |
— | — | — | — | — |
Major\PromotionItem :11 |
major_promotion_item :17 |
:19 |
— | promotion() :24 |
— | — | — |
Major\PromotionUsed :10 |
major_promotion_used :16 |
customer_id,promotion_id,promotion_item_id,order_id,order_item_id :18 |
— | — | — | — | — |
Notification :11 |
— | :13 |
:21 |
user() :24; customer() :28 |
— | store($token,$title,$body) :33 (FCM) |
— |
Notify :14 |
notify :17 |
title,customer_id,user_id,note,read,value,type,type_send,sender_id :21 |
read→bool :32 |
— | scopeMe :50 |
store($token,$title,$body) :57 (FCM push); sendToGroup($tokens,$title,$body) :88 |
— |
Order :16 (major/wholesale order) |
orders |
customer_id,reagent_id,type,input,output,remain,w,wage,city_id,price,percent,sts,confirmed,rial_input,discount :25 |
(empty :144) |
items() hasMany OrderItem :149; customer() :156; parent()→Customer by reagent_id :168; activity() hasMany OrderActivity :173; cashe() hasOne Major\Cash by order_id :232 |
scopeMe :161 |
$TYPES=[1=>ثبت سفارش توسط مسئول فروش, 2=>ثبت مشتری] :45; $CONFIRMED=[1=>تایید شده,2=>در انتظار تایید] :60; $STS = [0=>معلق, 1=>ثبت سفارش, 2=>تایید مدیر سیستم, 3=>درحال تامین, 4=>درحال آماده سازی, 5=>تحویل مسئول فروش, 6=>تحویل مشتری] :65; $STS_TAB :73; $STS_COLOR :105; $STS_IMG :122; $SELECT_COLOR,$SELECT_IMG :23-24; safeDelete($orderID) :211 |
getConfirmedStrAttribute :178, getColorAttribute :184, getImgAttribute :190, getInputAttribute :197, getPercentAttribute :202, getWageAttribute :207, getWAttribute :222, getTimeAttribute :227; $appends=['time','confirmed_str'] :121; $hidden :138 |
OrderActivity :10 |
order_activity :13 |
title,note,user_id,customer_id,order_id,meta,proceed,key :17 |
:28 |
order() :34; customer() :39; user() :44 |
— | — | — |
OrderItem :10 |
order_items |
order_id,variant_id,product_id,product_title,variant_title,percent,price,rial_pay,note,wage,qty,sts,w,rash_weight,original_rash_weight,discount,original_percent :15 |
— | product() :36; variants()→ProductVariant :40; order() :54 |
— | — | getWAttribute → Utility::round :45; getWageAttribute :49 |
Permission :7 |
permission :14 |
rid,ut :9 |
— | — | — | Composite PK ['rid','ut'] :16; $timestamps=false :17; $incrementing=false :18 |
— |
Product :14 |
product :20 |
title,body_html,desk_note,product_code,indicator_id_id,mobile_pic_id,number_of_purchase,is_active,brand_id,disabled,file_id,show_type,delivery_type,message_long_delivery,count_fav,count_order,count_view,min_gram,max_gram,offer_day,branch_id,inventory_id,is_exist,has_warranty :22 |
is_active,disabled,offer_day,is_exist,has_warranty→bool :60 |
images() :75; ciny() :79; thumb() :90; tmobile() :96; variants() (active) :102; variantsAll() :106; variantOne() :111; variantsPromotion() :116; collect() :123; category() :128; image() :140; brand()→ProductBrand :145; gallery() hasManyThrough :153; file() :187; tags() :192; promotion()→PromotionProduct :196; inventory()→InventoryBranch :204; branch() :209 |
scopeCool :69, scopeMobile :173, scopeSite :178, scopeActive :182 |
safeDelete($productId) :165 |
— |
ProductBrand :10 |
product_brand :17 |
:19 |
— | — | — | — | — |
ProductImage :9 |
products_productimage :14 |
:15 |
— | image() :22; product() :27 |
scopeMobile :32, scopeDesktop :37 |
— | — |
ProductTags :10 |
product_tags :16 |
product_id,const_id :18 |
— | product() :24; cnt()→ConfigStatic :28 |
— | $timestamps=false :15 |
— |
ProductVariant :15 |
products_productvarient :20 |
title,qty,grams,percentage_pay,product_id_id,barcode,color,width,length,height,rial_pay,inventory,details,description,meta,position,requires_shipping,taxable,is_pre_order,is_active :24 |
is_pre_order,is_active→bool; rial_pay,percentage_pay,grams→double :121 |
product() :312; promotion() :316; inventory()→InventoryTransaction :324; inventory_branch() :328 |
— | $product_price_extra_percent (loaded in boot() from ConfigStatic product_price_extra_percent, default 7) :45-52; $goldPrice :132; $dis_product :133; $COLOR_STR :57; $COLORS = [0=>سفید,1=>زرد,2=>شکلاتی,3=>رزگلد] :94 |
getPriceAttribute :156 (core gold price formula); getPriceWithDiscountAttribute :248; getColorStrAttribute :135; $appends=['price','color_str','price_with_discount'] :115 |
PromotionProduct :9 |
promotion_products |
promotion_id,promotion_item_id,product_variant_id,product_id,discount,type,active,start_at,end_at,use_only :12 |
active,use_only→bool :28 |
— | — | — | — |
RequestFashion :8 |
— | :11 |
— | — | — | — | — |
RequestLog :9 |
(request_logs) | customer_id,ip,device,data,user_agent,route,method :14 |
data→array :23 |
— | — | UPDATED_AT = null :12; $timestamps=['created_at'] :13 |
— |
SingleCustomer :13 (Authenticatable, guard api-singleCustomer) |
login :19 |
id,password,username,lname,fname,name,phone,email,user_type,is_active,last_login,token_sms,percent,birth_day,branch_id :21 |
— | transaction() :45; branch() :48 |
— | $hidden=['password'] :39 |
setPasswordAttribute (Hash) :41 |
SingleCustomer\OrderActivity :10 |
orders_histroy :17 |
:19 |
:28 |
— | — | — | — |
SingleCustomer\PromotionUsed :10 |
single_promotion_used :15 |
:17 |
— | — | — | — | — |
SingleCustomerAddress :13 |
accounts_address :19 |
reciver_lname,reciver_fname,reciver_phone,reciver_fixed_phone,province,city,zipcode,address,latitude,longitude,is_default,user_id_id :21 |
(empty :36) |
— | — | — | — |
SingleCustomerOrderItems :12 |
orders_orderitem :18 |
title,price,approximate_price,qty,deposit,amount_paid,approximate_gram,exact_gram,debtor_amount,is_active,supply_at,delivery_at,order_id,product_id,variant_id,grams,rial_pay,variant_title,is_preorder,promotion_id,promotion_item_id,total_discount,total_price,gold_price_in_formula,branch_id :20 |
is_preorder→bool :48 |
product() :54 |
— | — | — |
SingleCustomerOrders :13 (retail order) |
orders_orders :19 |
app,billing_address,browser_ip,buyer_accepts_marketing,email,phone,note,prcessing_method,processed_at,shipping_address,shipping_line,subtotal_price,discount_codes,total_discount,total_price (pre-discount),price (post-discount),total_tax,total_weight,tags,sts,is_active,canceled_at,canceled_reason,closed_at,send_time_id,user_id_id,gold_price,gold_price_original,type,reagent_id,use_wallet,payment_after_wallet,branch_id :21 |
shipping_address→array, use_wallet→bool :61 |
items() :84; customer()→SingleCustomer by user_id_id :93; user()→User by reagent_id; branch(); activity() hasMany SingleCustomer\OrderActivity |
— | $STS = [1=>ثبت سفارش, 2=>تایید مدیر سیستم, 3=>در حال تامین, 4=>در حال آماده سازی, 5=>خروج از انبار, 6=>ارسال, 7=>تحویل مشتری] :66; $TYPES = [1=>تلفنی,2=>تلگرام,3=>واتس آپ,4=>اینستا,5=>حضوری] :76 |
getStsStrAttribute :88; $appends=['sts_str'] :57 |
SingleCustomerTransaction :16 |
transactions_transaction :22 |
amount,transaction_type,sts,message,receipt,gateway,is_active,order_id_id,user_id_id :24 |
— | — | — | createAndGetToken($order,$ip) :38 — payping/zarinpal payment init (hardcoded amount 1000, hardcoded bearer token :86) |
— |
Sms :12 |
messages :16 |
customer_id,mobile,massage,token,type,user_id :44 |
— | — | — | $TYPES=[-1=>یک شماره تلفن,0=>همه کاربران,1=>کارشناسان فروش,2=>مشتریان عمده,9=>چند شماره تفن] :53; Send($to,$msg,…) :61; SendSms(...) :89; set(...) :125 |
— |
TransactionOrder :8 |
(transaction_orders) | customer_id,order_id,total_price,transaction_type,total_weight,order_date,payment :11 |
payment→bool :20 |
— | — | — | — |
User :12 (Authenticatable, guard api/web) |
users |
name,fname,lname,mobile,ut (user type = role id),city_id,token_mobile,branch_id :22 |
email_verified_at→datetime :48 |
user_type()→ConfigStatic by ut :51 |
— | $hidden=['password','remember_token'] :38; SoftDeletes :15 |
— |
Utility :6 |
(not a real table) | — | — | — | — | $formatJ='Y/n/j-H:i' :8; round($value) → round($value, 2) :10; convertDate() (Jalali) :15; faTOen() Persian/Arabic digit → ASCII :26; baseURLStorage() = https://henzagold.com/oapi/storage/ :30 |
— |
WebServiceGold :13 |
(not a real table) | — | — | — | — | getPriceGold18Ayar() :17 — reads ConfigStatic['gold_price'], geram18.p, strips commas, intval, /10 (rial→toman); getAllPrice() :27; getAllPriceFromWebService() :33 — ratebox.ir feed, maps 4→mesghal, 5→geram18, 6→geram24, writes ConfigStatic['gold_price'] only when all three present |
— |
Workshop :10 |
(workshops) | name,address,phone,user_id,is_active :13 |
is_active→bool :20 |
user()→Customer (note: class mismatch vs. column) :23 |
— | SoftDeletes :12 |
— |
Model count: 57 files under app/Models (incl. 6 in Major/, 2 in SingleCustomer/, and Selector.php which is a trait, not a model).
6. Database
6.1 Migrations — database/migrations (31 files)
| # | File | Op | Table | Key columns |
|---|---|---|---|---|
| 1 | 2014_10_12_000000_create_users_table.php |
create | users |
id, name, mobile unique, password, rememberToken, timestamps, softDeletes (:16-23) |
| 2 | 2014_10_12_100000_create_password_resets_table.php |
create | password_resets |
mobile index, token, created_at nullable (:16-19) |
| 3 | 2019_08_19_000000_create_failed_jobs_table.php |
create | failed_jobs |
id, uuid unique, connection, queue, payload, exception, failed_at useCurrent (:16-23) |
| 4 | 2020_10_01_120354_order_table.php |
create | orders |
id, customer_id uint, reagent_id uint null, type tinyint, input/output/remain/w/wage/percent double null, sts tinyint null, timestamps, softDeletes (:16-29) |
| 5 | 2020_10_01_120408_order_items_table.php |
create | order_items |
id, order_id, product_id, product_title, variant_title, w/wage/percent double null, timestamps (:16-25) |
| 6 | 2020_10_01_120430_customers_table.php |
create | customers |
id, fname(50), lname(50), name(75), mobile(20), ncode(20), password, input/output double, remain double default 0, rial_input/rial_output/rial_remain bigint uint, reagent_id, type/sts tinyint, timestamps, softDeletes (:16-34) |
| 7 | 2020_10_01_120914_cash_table.php |
create | cashes |
id, user_id, customer_id, input/output/remain double, rial_* bigint, type/sts tinyint, timestamps, softDeletes (:16-29) |
| 8 | 2020_10_19_153228_customer_add.php |
alter | customers |
+api_token(60), rnd(60), notify_count def 0, total_order def 0, gram_level double def 0, percent double def 0, open_order def 0, child def 0 (:26-34) |
| 9 | 2020_10_25_155247_customers_cols.php |
alter | customers |
+phone(15), address (:16-18) |
| 10 | 2020_10_25_164102_order_acitvity.php |
create+alter | order_activity; order_items; orders; cashes |
create order_activity: id,title(50),note,user_id,customer_id,order_id,meta json,timestamps (:16-24). alter order_items: +variant_id,price double,sts tinyint,qty (:26-30). alter orders: +price double (:32-34). alter cashes: +title,to,note,ayar(20),lab,balance double,value double,price bigint (:36-44) |
| 11 | 2020_10_25_170047_notify_table.php |
create | notify |
id,title,customer_id,user_id,note(512),type tinyint,value tinyint,read bool def false,timestamps (:16-25) |
| 12 | 2020_10_27_192859_proceed_activity.php |
alter | order_activity |
+proceed bool def false (:16-17) |
| 13 | 2021_09_18_115342_permissions_table.php |
create | permission |
rid string, ut int, primary(['rid','ut']) (:16-19) |
| 14 | 2021_09_18_164552_file_id_product.php |
alter | product |
+file_id uint null (:16-17) |
| 15 | 2021_09_18_171700_city_table.php |
create+alter | cities; users; orders |
create cities: id,title(50),parent,level,percent float,timestamps,softDeletes (:16-23). alter users: +ut uint null, city_id (:27-29). alter orders: +city_id (:32-33) |
| 16 | 2021_09_18_172722_cities_p_2.php |
alter | cities |
+percent_aux float null (:16-17) |
| 17 | 2021_09_21_160213_product_tags.php |
create | product_tags |
id increments, product_id, const_id (:16-19) |
| 18 | 2021_09_28_173620_customer_city_id.php |
alter | customers |
+city_id uint null (:16-17) |
| 19 | 2021_10_21_092358_fav_table.php |
create | fav |
customer_id, product_id, primary(['customer_id','product_id']) (:16-19) |
| 20 | 2021_10_21_094849_apk_log.php |
create | apk_log |
id,ip(15),version,created_at (:16-20) |
| 21 | 2021_11_01_155307_mobile_note.php |
alter | product |
+desk_note null (:16-17) |
| 22 | 2021_11_01_162712_cat_image.php |
alter | category_collection |
+image_id null (:16-17) |
| 23 | 2021_11_01_164540_cat_image_total.php |
alter | category_collection |
+total def 0 (:16-17) |
| 24 | 2021_11_03_113752_icon_category.php |
alter | category_collection |
+icon_id null (:16-17); down() targets category (mismatch, :28) |
| 25 | 2021_11_07_103558_product_gallery_id.php |
alter | products_productimage |
+w string null (:16-17) |
| 26 | 2021_11_15_202459_type_category.php |
alter | category_collection |
+type tinyint null (:16-17) |
| 27 | 2021_11_17_105202_body_category.php |
alter | category_collection |
+body null (:16-17) |
| 28 | 2021_11_23_114049_product_disabled.php |
alter | product; category_collection |
+disabled bool def false (:16-17); category_collection.disabled bool nullable(false) (:20-21) |
| 29 | 2021_12_18_161611_create_promotion_products.php |
create | promotion_products |
id,promotion_id,promotion_item_id,product_variant_id,product_id,discount_percent double,discount_price double,timestamps (:16-24) |
| 30 | 2024_06_14_232311_create_cinies.php |
create | cinies |
id,title(150),icon_id,collection_id,is_active bool def 1,description(1024),timestamps,softDeletes (:16-24) |
| 31 | 2024_06_21_203640_create_ciny_products.php |
create | ciny_products |
id,product_id,ciny_id,timestamps,softDeletes (:16-21) |
Package migration (autoloaded via WalletServiceProvider):
| File | Table | Columns |
|---|---|---|
packages/rooyesh/wallet/src/migrations/2021_12_02_065938_create_wallet_moudle_table.php:16-39 |
wallets |
id, owner_type enum(1=user,2=shop) def 1, timestamps, owner bigint, gold double (gold grams held), hash(128) null, credit bigint, unique(['owner','owner_type']) |
″ :41-56 |
transactions |
id, wallet bigint uint, transaction_type enum(1=gold,2=credit,3=expire) def 1, timestamps, value bigint, expire_at datetime null, hash(128) null, note text null, customer_id bigint uint null |
″ :58-66 |
transaction_metas |
transaction bigint uint, order_id bigint uint null, total_weight double uint null, percent int uint null, order_date timestamp null, id, timestamps |
Note:
transactionsmigration lacks abalancecolumn, butTransactionInterfacewrites$_inp['balance'](packages/rooyesh/wallet/src/interfaces/TransactionInterface.php:141) and hashes it (:110) — the column exists in the live DB but not in this migration.
6.2 Seeders — database/seeders
| File | Content |
|---|---|
database/seeders/DatabaseSeeder.php:14-17 |
run() is empty — the only line is a commented User::factory(10)->create() (:16). No seeders exist. |
Factory: database/factories/UserFactory.php (default Laravel).
6.3 Final schema (tables referenced by models but NOT in migrations)
These tables exist in the production DB (legacy/Django-imported; names like orders_orders, accounts_address, products_productvarient indicate a Django origin) and are only known through model $table + $fillable:
| Table | Model | Source |
|---|---|---|
login |
SingleCustomer |
app/Models/SingleCustomer.php:19 |
orders_orders |
SingleCustomerOrders |
app/Models/SingleCustomerOrders.php:19 |
orders_orderitem |
SingleCustomerOrderItems |
app/Models/SingleCustomerOrderItems.php:18 |
orders_histroy (sic) |
SingleCustomer\OrderActivity |
app/Models/SingleCustomer/OrderActivity.php:17 |
accounts_address |
SingleCustomerAddress |
app/Models/SingleCustomerAddress.php:19 |
transactions_transaction |
SingleCustomerTransaction |
app/Models/SingleCustomerTransaction.php:22 |
products_productvarient (sic) |
ProductVariant |
app/Models/ProductVariant.php:20 |
products_productimage |
ProductImage |
app/Models/ProductImage.php:14 |
product |
Product |
app/Models/Product.php:20 |
product_brand |
ProductBrand |
app/Models/ProductBrand.php:17 |
category_collection |
Category |
app/Models/Category.php:32 |
category_collect |
Collect |
app/Models/Collect.php:14 |
image |
Image |
app/Models/Image.php:13 |
config_statics |
ConfigStatic |
app/Models/ConfigStatic.php:15 |
messages |
Sms |
app/Models/Sms.php:16 |
major_promotion |
Major\Promotion |
app/Models/Major/Promotion.php:21 |
major_promotion_item |
Major\PromotionItem |
:17 |
major_promotion_used |
Major\PromotionUsed |
:16 |
major_promotion_ignores |
Major\PromotionIgnore |
:17 |
major_favorites |
Major\Favorite |
:14 |
single_promotion_used |
SingleCustomer\PromotionUsed |
:15 |
customers_test |
CustomerTest |
:18 |
kids |
Kids |
:15 |
transaction_orders |
TransactionOrder |
implicit |
branches, workshops, inventory_branches, inventory_transactions, custom_orders, custom_order_logs, comments, logs, request_logs, links, notifications, request_fashions |
respective models | implicit (no migration) |
Table count: 31 migration-created + 3 wallet package + ~28 legacy/implicit ≈ 62 tables. Only 34 have migrations.
7. Business logic
7.1 Gold price
| Concern | Where | Detail |
|---|---|---|
| Price source of truth | app/Models/ConfigStatic.php:15 key gold_price |
JSON blob with mesghal, geram18, geram24 (each with p price string, h, l, updated_at, uaj Jalali) |
| 18-ayar price read | app/Models/WebServiceGold.php:17-25 |
getPriceGold18Ayar() = intval(str_replace(',','', $data['geram18']['p'])) / 10 — rial→toman conversion baked in |
| All prices | app/Models/WebServiceGold.php:27-31 |
getAllPrice() returns whole decoded blob |
| Feed #1 (ratebox.ir) | app/Models/WebServiceGold.php:85-116 |
Http::get('https://api.ratebox.ir/apijson.php?token='.env('WEBSERVICE_TOKEN')); maps index 4→mesghal, 5→geram18, 6→geram24; only writes gold_price if all three arrive (:109-112) |
| Feed #2 (tgju.org) | app/Console/Commands/GetGoldPriceForPwa.php:45-71 |
https://call3.tgju.org/ajax.json, whitelist of 10 slugs (geram18, silver_999, mesghal, price_dollar_rl, sekeb, rob, nim, sekee_down, rob_down, nim_down); writes both gold_price_pwa and gold_price |
| Feed #3 (duplicate in web route) | routes/web.php:32-124 |
GET / runs the same tgju scrape inline and writes both keys |
| Feed #4 (unused) | app/Http/Controllers/Site/SiteController.php:261 |
ratebox again |
| Live price endpoints | routes/admin.php:51, routes/site.php:14, routes/api.php:47 |
GET admin/price, GET site/price (closures), GET api/price → ApiMobileController@PriceFromWebService:886 |
| No websocket / live push | — | see §10 |
7.2 Gram / weight calculation & pricing formula
Retail (SingleCustomer) price per variant — app/Models/ProductVariant.php:156-180 (getPriceAttribute):
G = ProductVariant::$goldPrice // injected per-request, = getPriceGold18Ayar()
E = static::$product_price_extra_percent // ConfigStatic 'product_price_extra_percent', default 7 (:45-52)
p = G + G * ((percentage_pay + E) / 100) // ساخت/اجرت (making charge %)
p = p + p * 0.07 // +7% (سود / profit margin)
t = p - G // isolate the non-metal portion
t = t + t * 0.09 // +9% VAT applied ONLY to the non-metal portion
p = G + t
p = p * grams
return floor(p / 1000) * 1000 // round DOWN to nearest 1,000 toman
Note rial_pay (stone cost) is not added in the current formula — only in the commented-out older variants (:183-206).
With promotion discount — app/Models/ProductVariant.php:248-296 (getPriceWithDiscountAttribute):
- Looks up
self::$dis_product(pre-loadedPromotionProductarray) byproduct_id_id(:250-252) - If
use_onlyand aSingleCustomer\PromotionUsedrow exists forauth()->id()+promotion_id→ discount forced to 0 (:253-257) type == 1→discount_percent; else →discount_price(a percent, applied as$price -= $price*($discount_price/100):293)- Discount percent is subtracted from the 7% margin:
$price += $price * (0.07 - $discount_percent/100)(:289) — i.e. a discount erodes margin, not metal - Same
floor(/1000)*1000rounding (:294)
Wholesale (major Customer) order gram math — app/Http/Controllers/Api/ApiMobileController.php:538-563 (setOrder):
percent = item.percent_pay - item.discount
gram_item = rash_weight + rash_weight * (percent/100)
allGram = Σ gram_item * qty // total gold grams owed
wage = Σ rash_weight * qty // net metal weight
order.wage = allGram - wage // the "اجرت" portion, in grams
rial_input = Σ rial_pay * qty // stone/other rial charges
discount = Σ item.discount
Per line item written at :617-634 with both rash_weight and original_rash_weight preserved, and w = rash_weight * (1 + percent/100).
Per-item implied gold price stored on retail orders — app/Http/Controllers/Controller.php:144:
gold_price_in_formula = (item.total_price / item.qty) / item.grams
7.3 Fees / commissions / tax / spread / rounding
| Item | Value | Where |
|---|---|---|
| Making-charge extra % | product_price_extra_percent ConfigStatic, default 7 |
app/Models/ProductVariant.php:45-52 |
| Profit margin | hardcoded 7% (0.07) |
ProductVariant.php:175, :289 |
| VAT | hardcoded 9% (0.09), applied only to price - goldPrice |
ProductVariant.php:178, :291 |
| Rounding (price) | floor($price/1000)*1000 — round down to 1,000 toman |
ProductVariant.php:180, :294 |
| Rounding (weight display) | round($value, 2) — 2 decimals |
app/Models/Utility.php:10-13; used by Order::getW/Wage, OrderItem::getW/Wage, Major\Cash::getValue |
| Cashback % | percent ConfigStatic (global) |
app/Http/Controllers/Adm/AdminController.php:994 |
| Cashback expiry (days) | expire ConfigStatic |
AdminController.php:995, :1002 |
| Birthday gift value | birthday_credit ConfigStatic |
app/Console/Commands/birthdayCommand.php:46 |
| Birthday gift expiry (days) | birthday_expire ConfigStatic |
birthdayCommand.php:47, :64 |
| City-level percent | cities.percent, cities.percent_aux |
database/migrations/2021_09_18_171700_city_table.php:21, 2021_09_18_172722_cities_p_2.php:17 |
| Per-customer percent | customers.percent / login.percent |
migration 2020_10_19_153228:32; SingleCustomer fillable :32 |
| No spread (buy vs sell price) | — | Not implemented. Single price per item. |
7.4 Wallet / balance — packages/rooyesh/wallet
Dual-currency wallet: gold (grams, double) and credit (toman, bigint), one row per (owner, owner_type) — packages/rooyesh/wallet/src/migrations/...:16-30.
| Concern | Where | Detail |
|---|---|---|
| Wallet open / get | WalletInterface::__construct :17-40 |
find-or-create by (owner_id, owner_type); validates hash on load |
| Hash chain (tamper detection) | WalletInterface::generate_hash :51-57 |
sha256(sha256(credit) + sha256(gold) + sha256(owner) + sha256(last_tx.hash) + "yhoenszeaf") — secret pepper is hardcoded |
| Wallet validate | WalletInterface::validate :42-49 |
throws UnprocessableEntityHttpException('امکان شارز این کیف پول وجود ندارد'); the package's own WalletValidateFailed is commented out (:45) |
| Transaction hash | TransactionInterface::generate_hash :101-114 |
sha256(sha256(value)+sha256(balance)+sha256(wallet)+"yhoenszeaf"+last_tx.hash) |
| Balance check | TransactionInterface::apply_transaction :127-135 |
if not deposit: type 1 (gold) requires wallet.gold >= value → NotEnoughCashBalance; type 2 (credit) requires wallet.credit >= value → NotEnoughCreditBalance |
| Sign convention | :136 |
value = abs(value) * (deposit ? 1 : -1) |
| Running balance | :141 |
balance = wallet.gold + wallet.credit + value — mixes grams and toman in one number (known modeling defect) |
| Validation rules | :142-153 |
wallet,type required; expire_at date; value integer|required (gram values are doubles — this rule is effectively bypassed because $validator->failed() is called instead of fails() at :151, which always returns an array/empty and never throws) |
| Apply to wallet | :159-165 |
type 1 → wallet.gold += value; type 2 → wallet.credit += value; then re-hash wallet |
| Meta rows | :157-158 |
TransactionMeta::create($meta) with order_id, total_weight, percent, order_date |
| Transaction types | migration :42-46 |
1=gold, 2=credit, 3=expire |
| Owner types | migration :27-30 |
1=user, 2=shop — all call sites pass 1 |
| Read wallet (customer) | app/Http/Controllers/Customer/CustomerController.php:14-19 |
gold, credit, + computed gold_toman = gold * getPriceGold18Ayar() |
| Wallet tx list (customer) | Customer/CustomerController.php:21-30 |
paginated via addLimit |
| Wallet tx list (admin) | app/Http/Controllers/Adm/WalletController.php:49-59 |
TableEngine |
| Admin manual charge | Adm/WalletController.php:19-39 |
deposit = value > 0; pre-check credit sufficiency; always type 2 (credit), expire_at = now()+1 year |
| Wallet config get/set | Adm/WalletController.php:61-79 |
setConst writes arbitrary ConfigStatic keys; getConfig returns percent+expire; getConfigBirthday returns birthday_credit+birthday_expire |
| Global percent reset | Adm/WalletController.php:41-46 |
SingleCustomer::query()->update(['percent' => …]) — updates every row |
Cashback on delivery — app/Http/Controllers/Adm/AdminController.php:985-1013 (chargeWalletAfterOrder):
percent = ConfigStatic['percent']; expire = ConfigStatic['expire']
value = transaction_order.total_weight * (percent / 100) // in GRAMS
new TransactionInterface(wallet, {value, order_id, expire_at: now()+expire days}, type=1 /*gold*/, deposit=true,
meta:{order_id, total_weight, percent, order_date})
transaction_order.payment = 1
Triggered from Controller::afterCreateOrder when sts == 6 (app/Http/Controllers/Controller.php:202-215), which also SMSes the customer the gram amount and "6-month validity" text (:207-214) — note the SMS says 6 months but the actual expiry is expire days from ConfigStatic.
Spending the wallet at checkout — app/Http/Controllers/Customer/OrderController.php:99-136:
if order.use_wallet:
gold_value_toman = wallet.gold * order.gold_price_original
all = gold_value_toman + wallet.credit
if all <= order.price: // wallet cannot cover → drain it
withdraw all gold (type 1) and all credit (type 2)
else: // wallet covers → partial
if wallet.gold <= order.total_weight: withdraw all gold;
if gold < total_weight: withdraw (all - order.price) credit
else: withdraw exactly order.total_weight grams
// recompute what is still payable
amount = Σ |tx.value| * gold_price_original (type 1) + Σ |tx.value| (type 2)
order.payment_after_wallet = order.price - amount
Refund on cancel — Customer/OrderController.php:150-168: re-deposits every Transaction for the order back into the wallet with the same transaction_type.
7.5 Buy / sell orders
There is no buy/sell order book, no market order, no limit order. Two distinct purchase order flows exist:
| Flow | Model/table | Entry point | Status enum |
|---|---|---|---|
| Wholesale ("major") order — shopkeeper orders gold goods from the wholesaler, denominated in grams | Order / orders, OrderItem / order_items, OrderActivity / order_activity |
ApiMobileController@setOrder :528-758 (guard api-customer); admin Adm\OrderController@store :32, Adm\MajorOrderController |
Order::$STS 0..6 — app/Models/Order.php:65-72 |
| Retail order — web customer buys a product, denominated in toman | SingleCustomerOrders / orders_orders, SingleCustomerOrderItems / orders_orderitem, SingleCustomer\OrderActivity / orders_histroy |
Customer\OrderController@store :68-148 (guard api-singleCustomer); admin Adm\AdminController@orderStsSingle :898 |
SingleCustomerOrders::$STS 1..7 — app/Models/SingleCustomerOrders.php:66-74 |
| Custom order (bespoke jewelry request) | CustomOrder, CustomOrderLog |
Api\CustomOrderController |
CustomOrder::$appends['sts_str_en'/'sts_str_fa'] :15, :68-76 |
7.6 Order & transaction status enums and transitions
Order::$STS (wholesale) — app/Models/Order.php:65-72:
| key | Persian | notes |
|---|---|---|
| 0 | معلق (suspended) | set when gram limit exceeded |
| 1 | ثبت سفارش (placed) | default happy path |
| 2 | تایید مدیر سیستم (sysadmin approved) | |
| 3 | درحال تامین (sourcing) | |
| 4 | درحال آماده سازی (preparing) | |
| 5 | تحویل مسئول فروش (handed to sales rep) | |
| 6 | تحویل مشتری (delivered) | triggers wallet cashback |
| 7 | (کنسل شده — commented out :71) |
Supporting statics: $STS_TAB (with -1 => همگی) :73-104; $STS_COLOR :105-113 (0 = #FF5252, 1-5 = #f5cb83, 6 = #4CAF50); $STS_IMG :122-130. $CONFIRMED = [1=>تایید شده, 2=>در انتظار تایید] :60-63. $TYPES = [1=>ثبت سفارش توسط مسئول فروش, 2=>ثبت مشتری] :45-48.
Transition mechanism (wholesale): all 7 status rows are pre-created in order_activity at order creation (ApiMobileController@setOrder:652-664), each with proceed 0/1. Advancing a status = flipping proceed=1 on that row — Adm\MajorOrderController@orderSts:121-211. On create: proceed = inValidOrder ? (key==0) : (key==1) (:662).
SingleCustomerOrders::$STS (retail) — app/Models/SingleCustomerOrders.php:66-74: 1=ثبت سفارش, 2=تایید مدیر سیستم, 3=در حال تامین, 4=در حال آماده سازی, 5=خروج از انبار, 6=ارسال, 7=تحویل مشتری. Types $TYPES = [1=تلفنی,2=تلگرام,3=واتس آپ,4=اینستا,5=حضوری] :76-82.
Same pre-create-all-rows pattern: Controller::createSingleOrderActivity:81-92; afterCreateOrder flips the requested sts row (:182-186) and fires cashback at sts==6 (:202). Note the mismatch: $STS[6] = 'ارسال' (shipped) not delivered, yet cashback fires at 6.
Major\Cash::$TYPES — app/Models/Major/Cash.php:56-62: 9=سفارش (order), 1=آب شده (melted/bullion), 2=حواله (transfer note), 3=چک (cheque), 4=پولی (cash). $STS = [-1=>بررسی نشده, 1=>ثبت سند] :63-66. $CONFIRMED = [1=>تایید شده, 0=>تایید نشده] :68-71.
Wallet transaction types: 1=gold, 2=credit, 3=expire (migration :42-46).
SingleCustomerTransaction.sts is a free-text Persian string (e.g. 'پرداخت نشده' — app/Models/SingleCustomerTransaction.php:43), not an enum.
7.7 KYC levels
No KYC-level system exists. What exists is a two-step manual verification flag on wholesale customers:
| Field | Where |
|---|---|
customers.sts_verify_step_one, customers.sts_verify_step_two |
app/Models/Customer.php:18 fillable |
Accessors sts_verify_step_one_str, sts_verify_step_two_str + lookups GetStsVerifyStepOne, GetStsVerifyStepTwo |
app/DB/Selector.php:101-127 |
Document images: business_license_image_id (جواز کسب), shop_image_id (سر در فروشگاه), ncode_image_id (کارت ملی) |
app/Models/Customer.php:18; relations :170-181 |
| Admin approval | Adm\MajorCustomerController@verifyRegister:97-144, @indexVerify:157, @archive:175 |
| Activation toggles | Adm\AdminController@customerToggleSts:426, @customerToggleActive:432 |
| National code | customers.ncode (migration 2020_10_01_120430:22) |
No tiered limits are derived from verification status.
7.8 Limits (min / max / daily)
No daily limits. No min/max order amount. No withdrawal limit. The only limit is a per-customer gram ceiling on wholesale orders:
| Concern | Where |
|---|---|
| Ceiling field | customers.gram_level double default 0 — database/migrations/2020_10_19_153228_customer_add.php:31; fillable app/Models/Customer.php:18 |
| Running usage | customers.remain double default 0 — database/migrations/2020_10_01_120430_customers_table.php:26 |
| Check | app/Http/Controllers/Api/ApiMobileController.php:566-567: $inValidOrder = ($allGram + $remain) > $gramLevel |
| Effect | order sts forced to 0 (معلق/suspended) instead of 1 (:577, :592); activity note "تعلیق سفارش به دلیل عبور از سقف مجاز گرمی" (:661); a Notify row explains the suspension (:669-677) |
| Note | The $customer->increment('remain', $allGram) on success is commented out (:604-607) — remain is maintained elsewhere (cash ledger) |
| Product-level gram bounds | product.min_gram, product.max_gram — app/Models/Product.php:22 (display/filter only) |
| Pagination limit | Controller::addLimit — default 10, hard cap 50 — app/Http/Controllers/Controller.php:31-36 |
| Rate limit | 500 req/min on api — app/Providers/RouteServiceProvider.php:77 |
7.9 OTP / SMS
| Concern | Where | Detail |
|---|---|---|
| SMS gateway (active) | app/Models/Sms.php:74-84 (Send), :101-111 (SendSms) |
POST https://smspanel.trez.ir/SendMessageWithCode.ashx, form fields PhoneNumber=9998882797, Username=hajiabolfath, Password=Aa@09195540836 (hardcoded), Mobile, Message; 20s timeout |
| SMS gateway (dead) | Sms.php:63-73, :91-99 |
0098sms.com/sendsmslink.aspx with USERNAME=zsms6916 — commented out |
| Every send is logged | Sms::set :125-134 → messages table |
customer_id, mobile, massage(sic), token, type, user_id |
OTP — wholesale Customer |
Api\ApiMobileController@userAuth:40-50 |
rand(1000,9999) → stored in customers.send_password (plain text, no expiry, no attempt counter); SMS body includes <#> code is … + Android SMS Retriever hash aMo6iFyUQaY |
| OTP verify (wholesale) | ApiMobileController@userVerfiy:52-81 |
compares Utility::faTOen($request->password) != $customer->send_password → abort(422); on success issues api_token = Str::random(60) only if null (:59-61) — token never rotates |
OTP — retail SingleCustomer |
Api\SingleCustomerController@login:58-76 |
rand(1000,9999) → login.token_sms (plain, no expiry); returns {id}; SMS "کد تایید ورود" |
| OTP verify (retail) | Api\SingleCustomerController@verfiy:42-56 |
compares token_sms; sets is_active = true; issues api_token = Str::random(60) if null |
| Legacy password login | ApiMobileController@login:83-110 (Hash::check); Adm\AdminController@login:60-78 (staff) |
|
| Batch SMS | Adm\SmsController@batch:23-76 |
validates payload,type numeric,mobiles array,token; @replaceName:91-111 does %%NAME%% substitution |
| Ad-hoc SMS | Adm\SmsController@sendSmsToOther:150 |
|
| Mass-SMS to ALL customers via GET | routes/api.php:126-180 (GET api/send/all), routes/web.php:158-186 (GET /test2) |
unauthenticated closures that loop Customer::get() and SMS everyone |
| Hardcoded admin phones (order alerts) | ApiMobileController:601-604 (09128081392, 09124871664, 09124406015, 09120363240); Customer/OrderController:139-144 (09128081392, 09124406015 ×2, 09363366849) |
7.10 Notifications (push)
| Concern | Where |
|---|---|
| FCM config | config/fcm.php:4-9 — FCM_PROTOCOL (def http), FCM_SERVER_KEY, FCM_SENDER_ID |
| In-app notification store | Notify model / notify table — app/Models/Notify.php:14-33 |
| Single push | Notify::store($token,$title,$body) :57-86 |
| Group push | Notify::sendToGroup($tokens,$title,$body) :88+ |
| Second impl | Notification::store() app/Models/Notification.php:33 |
| Device token storage | customers.token_mobile, users.token_mobile (Customer.php:18, User.php:29); updated via POST api/tokenmobile → ApiMobileController@updateTokenMobile:477 |
| Admin send | Adm\NotifyController@store:27, @customer:67 |
| Read/unread | Notify.read bool; Adm\NotifyController@read:95, @getUnreadNotify:86; customer PUT api/notify/read/{id} → @readNotify:784 |
7.11 Payment gateway + callbacks
| Concern | Where | Detail |
|---|---|---|
| Gateway: PayPing (init) | app/Http/Controllers/Customer/TransactionController.php:11-27 |
POST https://api.payping.ir/v1/pay with clientRefId, amount, returnUrl = https://henzagold.com/oapi/site/transaction/verify. No Authorization header is sent (the withHeaders call is chained after post() at :100, so it is a no-op). |
| Gateway: PayPing (verify, dead code) | app/Models/SingleCustomerTransaction.php:84-100 |
POST https://api.payping.ir/v2/pay/verify with hardcoded bearer token :86; hardcoded amount=1000, payerIdentity='09134139430', payerName='Azizan'; returnUrl = url('/bank-back') |
| Gateway: Zarinpal (SOAP) | SingleCustomerTransaction.php:49-82 |
entirely commented out |
| Callback route | — | The returnUrl site/transaction/verify is NOT registered in any route file. routes/site.php has no transaction/* route. /bank-back is also not registered. The payment callback is missing / dead. |
| Transaction record | transactions_transaction via SingleCustomerTransaction |
gateway = 'paypal' (sic, hardcoded :44), sts free-text Persian |
| Route | POST cu/transaction/gateway — routes/customer.php:36 |
7.12 File uploads
| Concern | Where |
|---|---|
| Primary upload | Adm\FileController@storeWithoutData:144-192 — POST admin/file/create, POST api/file/create |
| Filename | md5(time() . original_name) . '.' . ext (:155-156) |
| Destination | public_path('storage') — flat, no date directory (the createDir() path logic is commented out :150, :162-179) |
| Record | App\Models\Image::create($data) with original_name, ext, image (:186-190) |
| No validation | no mime/size/extension check, no auth on admin/file/create |
| WebP conversion / watermark | commented out (:162-172) |
| Body/caption update | @updateBody:268 — PUT admin/file/update/{file_id} |
| Full CRUD (legacy) | @store:58, @show:200, @update:215, @destroy:255 |
| Product image resize | Adm\ProductController@createImage:22-29 |
| URL base | Utility::baseURLStorage() = https://henzagold.com/oapi/storage/ — app/Models/Utility.php:30-32; Image::getFullAttribute:35, getImageAttribute:58 |
| APK download | Api\SiteController@downloadApk — env('APK_PATH', storage_path('app/public/henza.apk')), env('APK_VERSION',0) — app/Http/Controllers/Api/SiteController.php:494-495 |
7.13 Settings / config table
config_statics (ConfigStatic) is the universal key/value settings table — app/Models/ConfigStatic.php:10-33. It doubles as a lookup/enum table (users.ut is an FK to it — Adm\UserController:26 validates ut exists:config_statics,id; User::user_type() :51).
| Known key | Purpose | Evidence |
|---|---|---|
gold_price |
live price JSON (geram18/geram24/mesghal) | WebServiceGold.php:19,:28,:110 |
gold_price_pwa |
PWA price JSON (10 instruments) | GetGoldPriceForPwa.php:70; routes/web.php:60 |
product_price_extra_percent |
making-charge extra %, default 7 | ProductVariant.php:49 |
percent |
wallet cashback % of order weight | AdminController.php:994; Controller.php:203 |
expire |
cashback validity, in days | AdminController.php:995,:1002 |
birthday_credit |
birthday gift amount (toman) | birthdayCommand.php:46 |
birthday_expire |
birthday gift validity (days) | birthdayCommand.php:47 |
brand |
product brand list (legacy, superseded by product_brand) |
ApiMobileController.php:75 (commented) |
| (arbitrary) | Adm\WalletController@setConst:61-70 writes any key from the request body |
Accessors: ConfigStatic::getValue($key) — returns scalar if exactly 1 row, collection if >1, throws NotFoundHttpException('Const not found') if 0 (:25-33). CRUD via Adm\ConstController (admin/const/*), read via GET site/const/{id}, full list via GET admin/config/statics → AdminController@getConfigStatics:752.
7.14 What does NOT exist (explicit negatives for parity work)
| Expected in a gold-banking backend | Status in henza_server |
|---|---|
| Buy / sell gold orders (market/limit) | Absent — only product purchase orders |
| Bid/ask spread | Absent — one price per item |
| Deposit (cash in) | Absent — only admin manual wallet charge (Adm\WalletController@charge) |
| Withdraw (cash out / physical gold delivery) | Absent |
| Peer-to-peer transfer | Absent (the "حواله" in Cash::$TYPES[2] and config/havaleh.php is a static list of 9 broker names, not a transfer feature) |
| KYC levels / tiers | Absent — only 2 manual verification booleans + 3 document images |
| Daily / monthly limits | Absent — only a per-customer total gram ceiling |
| Payment callback / verify endpoint | Route missing (§7.11) |
| Idempotency keys on money ops | Absent |
| DB transactions around wallet ops | Absent — apply_transaction does 4 unwrapped writes (TransactionInterface.php:154-164) |
| Audit/event sourcing | Partial — wallet hash chain + order_activity + RequestLog |
8. Jobs / Queues / Cron
8.1 Jobs — app/Jobs (3)
| Job | Constructor args | handle() |
Evidence |
|---|---|---|---|
SendSmsJob |
$mobile, $message, $customer_id, $user_id |
Sms::SendSms($mobile,$message,$customer_id,null,null,$user_id) |
app/Jobs/SendSmsJob.php:25-41 |
SendSmsAfterCreate |
$mobile, $message |
Sms::Send($mobile,$message) |
app/Jobs/SendSmsAfterCreate.php:23-37 |
PromotionAfterCreate |
$customer_id |
body fully commented out; return; — "new customer 1% promo for 5 days" disabled |
app/Jobs/PromotionAfterCreate.php:33-53 |
All three implement ShouldQueue with Dispatchable, InteractsWithQueue, Queueable, SerializesModels.
Queue driver: config/queue.php 'default' => env('QUEUE_CONNECTION', 'sync') — defaults to sync (jobs run inline) unless env overrides. failed_jobs table exists (migration #3).
8.2 Console commands — app/Console/Commands (5)
| Signature | Class | Purpose |
|---|---|---|
price:get |
GetGoldPrice :15 |
WebServiceGold::getAllPriceFromWebService() (ratebox.ir) — :39-43 |
pwa:price |
GetGoldPriceForPwa :18 |
tgju.org scrape → writes gold_price_pwa and gold_price; then calls Tahesab DoListMoshtari [1,510] at https://31.7.68.147:3030/ with hardcoded bearer token :76-81 |
transaction:expire |
ExpireCommand :18 |
loops all SingleCustomer; sums expired-vs-spent gold and credit; posts negative (withdraw) TransactionInterface entries for the surplus — :42-80 |
birthday:sms |
birthdayCommand :20 |
finds customers whose birth_day day+month = today; SMSes a gift message; deposits birthday_credit as type 2 (credit) with expire_at = now() + birthday_expire days — :44-68 |
wallet:sms |
SmsWalletCommand :17 |
finds wallets with sms_at exactly 3 months ago; if gold>0 || credit>0 SMSes the owner the literal string 'هنزا'; updates sms_at/sent — :41-57 |
8.3 Schedule — app/Console/Kernel.php
| Item | Evidence |
|---|---|
$commands registry |
birthdayCommand, ExpireCommand, GetGoldPriceForPwa — app/Console/Kernel.php:18-22 (note: GetGoldPrice and SmsWalletCommand are not listed, but $this->load(__DIR__.'/Commands') at :42 auto-discovers them) |
schedule() |
EMPTY — the only line is a commented $schedule->command('inspire')->hourly(); — app/Console/Kernel.php:30-33 |
⇒ There is NO Laravel cron schedule. Price refresh, expiry sweeps and birthday SMS must be driven by external OS cron calling artisan pwa:price / transaction:expire / birthday:sms, or by hitting GET / (routes/web.php:32) which performs the price scrape inline.
routes/console.php:17-19 defines only the stock inspire closure command.
9. Permissions / roles
No Spatie, no Gates, no Policies. AuthServiceProvider::$policies is empty (app/Providers/AuthServiceProvider.php:15-17); boot() only calls registerPolicies() (:24-29). No Gate::define anywhere. The can middleware alias is registered (Kernel.php:60) but never used on any route.
9.1 Model
| Piece | Detail | Evidence |
|---|---|---|
Role = users.ut |
integer "user type" on User; FK into config_statics |
migration 2021_09_18_171700_city_table.php:28; User.php:27; User::user_type() :51 |
Permission = permission table |
composite PK (rid, ut) — rid is a free-text permission string, ut is the role id |
migration 2021_09_18_115342_permissions_table.php:16-19; app/Models/Permission.php:14-18 |
Validation of ut |
'ut' => 'required|numeric|exists:config_statics,id' |
Adm\UserController.php:26, :64 |
9.2 Where permissions are read
| Operation | Where |
|---|---|
| Returned at login | Adm\AdminController@login:74 — $per = Permission::whereUt($user->ut)->get(); attached to the login response. The server never enforces it — enforcement is entirely client-side in the admin SPA. |
| Set (replace all for a role) | Adm\PermissionController@create:12-40 — diffs requested roles[] against existing, creates missing, deletes surplus |
| Set (additive) | @store:42-57 — firstOrCreate per role |
| Delete one | @destroy:59-65 — DELETE admin/roles/{ut}/{rid} |
| Check one | @has:67-74 — GET admin/roles/{ut}/{rid} → boolean |
| My permissions | @get:76-81 — Permission::where('ut', Auth::user()->ut) |
| Permissions of a role | @getByUt:83-88 — GET admin/roles/{id} |
| Attached to user detail | Adm\UserController@show:96 — Permission::where('ut',$user->ut)->pluck('rid') |
9.3 Permission names found
No permission (rid) string literals exist anywhere in the codebase. rid values are created purely from client-supplied roles[] arrays (PermissionController@create:21, @store:51) and stored as-is. The catalogue of permission names lives only in the admin front-end and in the DB — it is not derivable from henza_server. Likewise there is no seeded list of ut (role) values; they are rows in config_statics.
9.4 Actual enforcement in practice
| Surface | Enforcement |
|---|---|
routes/admin.php (215 routes) |
NONE — the auth:api wrapper is commented out (:12, :264). Fully public. |
routes/api.php public block |
none |
routes/api.php:64-117 |
auth:api-customer only (authentication, not authorization) |
routes/customer.php:10-46 |
auth:api-singleCustomer only |
routes/site.php, routes/web.php |
none (except version on one route) |
| Ownership checks | ad-hoc: Controller::checkCustomer($auth_id,$store_id) throws AccessDeniedHttpException (app/Http/Controllers/Controller.php:232-236); scopes Order::scopeMe:161, Notify::scopeMe:50, Major\Cash::scopeMe:74; where('customer_id', auth()->id()) in Customer\CustomerController:135 etc. |
10. Broadcasting / sockets
| Item | Detail | Evidence |
|---|---|---|
| Channels file | Contains exactly one channel: App.Models.User.{id}, authorized by (int)$user->id === (int)$id (Laravel's stock private-notification channel) |
routes/channels.php:28-30 |
| Provider | BroadcastServiceProvider exists |
app/Providers/BroadcastServiceProvider.php |
| Driver default | 'default' => env('BROADCAST_DRIVER', 'null') — null (disabled) unless env overrides |
config/broadcasting.php:18 |
| Available connections | pusher (:34, keys PUSHER_APP_KEY/PUSHER_APP_SECRET/PUSHER_APP_ID/PUSHER_APP_CLUSTER), redis (:45), log (:50), null (:54) |
config/broadcasting.php:31-56 |
| Events broadcast | NONE — no class implements ShouldBroadcast; app/Events/ does not exist; EventServiceProvider::$listen is stock |
app/Providers/EventServiceProvider.php |
| Live price over socket | NOT IMPLEMENTED. Price is delivered by polling GET api/price / GET site/price / GET admin/price, all of which read ConfigStatic['gold_price'] |
routes/api.php:47, routes/site.php:14-16, routes/admin.php:51-53 |
| Real-time client hint | package.json may include laravel-echo but no server-side publisher exists |
— |
⇒ There is no real-time/websocket layer. Live price = HTTP polling of a DB-cached JSON blob refreshed by a cron-driven command.
11. Env / config keys
11.1 Custom (non-stock) config files
| File | Content |
|---|---|
config/havaleh.php:5-16 |
Flat array of 9 hardcoded broker name+phone strings (e.g. 'مسعود آتشی | 33977786-021'). Returned verbatim by GET admin/havale/list (Adm\AdminController@getHavaleList:1018) and attached to the mobile login payload as $customer->to (ApiMobileController:66, :96). |
config/version.php:2-4 |
['version' => '2.2.0'] — compared against the version request header by VersionMiddleware (app/Http/Middleware/VersionMiddleware.php:21-27). |
config/validation.php:2-9 |
Single route-keyed rule set: 'admin/product/create@post' => ['cats'=>'required|array','title'=>'required','indicator_id'=>'required','mobile_pic'=>'required']. Never read by any code (no config('validation') usage) — dead config. |
config/corcel.php |
Corcel/WordPress bridge connection. |
config/fcm.php:4-9 |
FCM_PROTOCOL (def http), FCM_SERVER_KEY, FCM_SENDER_ID. |
config/pdf.php, config/dompdf.php |
PDF rendering (invoice generation). |
11.2 env() calls inside app/ and routes/ (outside config/)
| Key | Default | Where |
|---|---|---|
WEBSERVICE_TOKEN |
— | app/Models/WebServiceGold.php:85; app/Http/Controllers/Site/SiteController.php:261; app/Console/Commands/GetGoldPriceForPwa.php:170 (commented) |
APK_VERSION |
0 |
app/Http/Controllers/Api/SiteController.php:494 |
APK_PATH |
storage_path('app/public/henza.apk') |
app/Http/Controllers/Api/SiteController.php:495 |
APP_NAME |
— | app/DB/Te/print.blade.php:5 |
BASE_PATH_STORAGE |
'' |
app/Models/Image.php:60 (commented out) |
⚠️ These are runtime
env()calls outside config files — they returnnullwhenphp artisan config:cacheis used.
11.3 Stock env keys consumed via config/*
APP_NAME, APP_ENV, APP_KEY, APP_DEBUG, APP_URL, LOG_CHANNEL;
DB_CONNECTION (default 'localhost' — unusual, config/database.php:18), DB_HOST, DB_PORT, DB_DATABASE, DB_USERNAME, DB_PASSWORD, DB_SOCKET, DATABASE_URL, DB_FOREIGN_KEYS, MYSQL_ATTR_SSL_CA;
REDIS_CLIENT, REDIS_CLUSTER, REDIS_PREFIX, REDIS_URL, REDIS_HOST, REDIS_PASSWORD, REDIS_PORT, REDIS_DB, REDIS_CACHE_DB;
BROADCAST_DRIVER (def null), PUSHER_APP_KEY, PUSHER_APP_SECRET, PUSHER_APP_ID, PUSHER_APP_CLUSTER;
CACHE_DRIVER, CACHE_PREFIX, MEMCACHED_*, DYNAMODB_CACHE_TABLE, DYNAMODB_ENDPOINT;
QUEUE_CONNECTION, SESSION_DRIVER, SESSION_LIFETIME;
FILESYSTEM_DRIVER, FILESYSTEM_CLOUD, AWS_ACCESS_KEY_ID, AWS_SECRET_ACCESS_KEY, AWS_DEFAULT_REGION, AWS_BUCKET;
MAIL_*, MAILGUN_DOMAIN, MAILGUN_SECRET, MAILGUN_ENDPOINT, POSTMARK_TOKEN;
FCM_PROTOCOL, FCM_SERVER_KEY, FCM_SENDER_ID.
11.4 Hardcoded secrets / endpoints (parity + security relevant)
| Secret / endpoint | Location |
|---|---|
SMS panel user + password hajiabolfath / Aa@09195540836 |
app/Models/Sms.php:80-81, :107-108 |
PayPing bearer 413471e0…d7b1 |
app/Models/SingleCustomerTransaction.php:86 |
Tahesab bearer S3F1P8Q4…U8 + host 31.7.68.147:3030 |
app/Console/Commands/GetGoldPriceForPwa.php:78-80 |
Wallet hash pepper "yhoenszeaf" |
packages/rooyesh/wallet/src/interfaces/WalletInterface.php:56; TransactionInterface.php:112 |
Storage base URL https://henzagold.com/oapi/storage/ |
app/Models/Utility.php:31 |
Payment return URL https://henzagold.com/oapi/site/transaction/verify |
app/Http/Controllers/Customer/TransactionController.php:99 |
| Admin alert phone numbers | app/Http/Controllers/Api/ApiMobileController.php:601-604; app/Http/Controllers/Customer/OrderController.php:139-144 |
Customer-facing URLs (henzagold.com/customer/my-orders, /dashboard, /app, /download/henza.apk) |
app/Http/Controllers/Controller.php:199, :213; routes/web.php:128, :132 |
12. Validation
There are ZERO FormRequest classes — app/Http/Requests/ does not exist. All validation is inline, using either $this->validate($request, [...]) (ValidatesRequests trait) or Validator::make($request->all(), [...]). config/validation.php defines one route-keyed rule set that nothing reads.
Distribution (rule-block counts per controller):
| Controller | blocks |
|---|---|
Adm/AdminController |
17 |
Api/ApiMobileController |
5 |
Api/SingleCustomerController |
4 |
Adm/MajorOrderController, Adm/UserController, Api/CustomOrderController, Api/SiteController |
3 each |
Adm/BranchController, Adm/OrderController, Adm/PermissionController, Adm/ProductController, Adm/SmsController, Adm/WorkshopController, Major/CustomerController |
2 each |
Adm/CitiesController, Adm/CommentController, Adm/MajorCustomerController, Adm/SingleCustomerController, Customer/CommentController, Customer/FavController, Customer/OrderController, WebApp/AuthController |
1 each |
Main rule sets
| Endpoint | Rules | Evidence |
|---|---|---|
| Admin login | phone: required, password: required |
Adm/AdminController.php:62 |
| Update customer | id: required|exists:customers,id, fname: required, lname: required |
Adm/AdminController.php:264-267 |
| Update customer (mobile uniqueness) | mobile: unique:customers,mobile,{id} |
Adm/AdminController.php:303-304 |
| Create customer (with reagent) | mobile: required|unique:customers, reagent: required |
Adm/AdminController.php:321-323 |
| Create customer (reagent path) | mobile: required|unique:customers, percent: required |
Adm/AdminController.php:352-354 |
| Confirm cash doc | id: required |
Adm/AdminController.php:455-456 |
| Set gram for fin-doc (commented) | id: required, gram: required |
Adm/AdminController.php:480-482 |
| Read SMS (commented) | FROM/TO/TEXT: required |
Adm/AdminController.php:505-508 |
| Confirm order | cId: required (customer), oId: required (order) |
Adm/AdminController.php:517-519 |
| Set fin-doc (commented) | customer_id/price/value: required |
Adm/AdminController.php:583-586 |
| Add product | cats: required|array, title: required |
Adm/AdminController.php:600-602 |
| Get variant(s) | id: required |
Adm/AdminController.php:736, :745 |
| Add category | title: required |
Adm/AdminController.php:794-795 |
| Change percent (bulk) | percentage_pay: required |
Adm/AdminController.php:845-846 |
| Report order | id: required |
Adm/AdminController.php:900-901 |
| Branch store/update | user_id: required |
Adm/BranchController.php:48-49, :83-84 |
| Cities store | title: required, parent: exists:cities,id, level: numeric|required, percent: numeric |
Adm/CitiesController.php:15-19 |
| Comment status | comment_id: required, sts: required |
Adm/CommentController.php:123-124 |
| Verify major customer | customer_id: required |
Adm/MajorCustomerController.php:98-99 |
| Major order sts | id: required |
Adm/MajorOrderController.php:123-124 |
| Major order item edit | id: required, w: required, order_id: required |
Adm/MajorOrderController.php:214-217 |
| Delete major order | id: required |
Adm/MajorOrderController.php:275-276 |
| Admin order store | order_items: required |
Adm/OrderController.php:35-36 |
| Admin order update | order_items: required, shipping_address: required |
Adm/OrderController.php:66-67 |
| Permissions (create/store) | ut: required, roles: required|array |
Adm/PermissionController.php:13-15, :45-47 |
| Product store | cats: required|array, title: required (product_code: required|unique:product,product_code is commented out :45) |
Adm/ProductController.php:42-45 |
| Product update | (rule array empty — product_code unique rule commented out) |
Adm/ProductController.php:114-115 |
| Single customer store | fname: required, lname: required, phone: required|unique:login |
Adm/SingleCustomerController.php:20 |
| SMS batch | payload: required, type: required|numeric, mobiles: array, token: required |
Adm/SmsController.php:25-29 |
| SMS to other | payload: required, mobile: required |
Adm/SmsController.php:79-81 |
| User store | fname: required, lname: required, mobile: required|unique:users, ut: required|numeric|exists:config_statics,id, city_id: exists:cities,id, password: required|min:6 |
Adm/UserController.php:22-28 |
| User update | mobile: unique:users,mobile,{id}, ut: numeric|exists:config_statics,id, city_id: exists:cities,id; if password present: password: required|min:6|confirmed |
Adm/UserController.php:62-72 |
| OTP request (wholesale) | username: required |
Api/ApiMobileController.php:42 |
| OTP verify (wholesale) | username: required, password: required |
Api/ApiMobileController.php:54 |
| Legacy login (wholesale) | username: required, password: required |
Api/ApiMobileController.php:85 |
| Retail register | fname: required, lname: required, phone: required|unique:login |
Api/SingleCustomerController.php:30 |
| Retail OTP verify | token: required, id: required |
Api/SingleCustomerController.php:43 |
| Retail login (OTP request) | phone: required |
Api/SingleCustomerController.php:59 |
| Retail order store | order_items: required, shipping_address: required |
Customer/OrderController.php:73-75 (returns 422 with $validator->errors()) |
Notable validation gaps (parity-relevant)
| Gap | Evidence |
|---|---|
setOrder (wholesale order creation) has NO validation at all — $request->items is consumed raw |
Api/ApiMobileController.php:528-758 |
Wallet charge has NO validation — $data['value'], $data['customer_id'] taken raw |
Adm/WalletController.php:19-39 |
setConst writes arbitrary ConfigStatic keys with no whitelist/validation |
Adm/WalletController.php:61-70 |
| File upload has no mime/size/extension validation | Adm/FileController.php:144-192 |
Payment gateway gateway() has no validation — amount, customer_id raw |
Customer/TransactionController.php:11-27 |
Wallet package's own validator is never enforced — calls $validator->failed() (returns array) instead of fails() (returns bool) |
packages/rooyesh/wallet/src/interfaces/TransactionInterface.php:150-153 |
Product::update validation array is empty |
Adm/ProductController.php:114-116 |
No numeric/min/max on any money or weight field anywhere |
— |