| @@ -9,8 +9,9 @@ | ||
| 9 | 9 | use FluentCart\App\Http\Controllers\FrontendControllers\CustomerController; |
| 10 | 10 | use FluentCart\App\Http\Controllers\FrontendControllers\CustomerOrderController; |
| 11 | 11 | use FluentCart\App\Http\Controllers\FrontendControllers\CustomerProfileController; |
| 12 | 12 | use FluentCart\App\Http\Controllers\FrontendControllers\CustomerSubscriptionController; |
| 13 | +use FluentCart\App\Http\Controllers\FrontendControllers\ProductReviewFrontendController; | |
| 13 | 14 | use FluentCart\App\Http\Controllers\ShopController; |
| 14 | 15 | use FluentCart\App\Http\Controllers\UserController; |
| 15 | 16 | use FluentCart\App\Modules\Shipping\Http\Controllers\Frontend\ShippingFrontendController; |
| 16 | 17 | use FluentCart\Framework\Http\Router; |
| @@ -46,18 +47,18 @@ | ||
| 46 | 47 | $router->post('login', [UserController::class, 'login']); |
| 47 | 48 | }); |
| 48 | 49 | |
| 49 | 50 | $router->prefix('customers') |
| 50 | - ->withPolicy('CustomerFrontendPolicy')->group(function (Router $router) { | |
| 51 | - //$router->post('/', [CustomerController::class, 'store']); | |
| 52 | - $router->get('/{customerId}', [CustomerController::class, 'getDetails']); | |
| 53 | - $router->put('/{customerId}', [CustomerController::class, 'updateDetails']); | |
| 54 | - $router->get('/{customerId}/orders', [CustomerController::class, 'getCustomerOrders']); | |
| 51 | + ->withPolicy('PublicPolicy')->group(function (Router $router) { | |
| 52 | + // Customer self-service (details/orders/address CRUD) lives under the | |
| 53 | + // customer-profile group — the duplicates that used to sit here shadowed | |
| 54 | + // the admin customers group and were unreachable dead code (audit #5). | |
| 55 | + // Only these checkout-context routes, with no admin counterpart, remain. | |
| 56 | + // PublicPolicy rather than a login gate (audit #6): guests reach these | |
| 57 | + // from checkout, and both controllers fully self-guard (current-customer | |
| 58 | + // resolution + ownership), answering guests with their own envelopes. | |
| 55 | 59 | $router->get('/{customerAddressId}/update-address-select', [CustomerController::class, 'updateAddressSelect']); |
| 56 | - $router->put('/{customerId}/address', [CustomerController::class, 'updateAddress']); | |
| 57 | 60 | $router->post('/add-address', [CustomerController::class, 'createAddress']); |
| 58 | - $router->delete('/{customerId}/address', [CustomerController::class, 'removeAddress']); | |
| 59 | - $router->post('/{customerId}/address/make-primary', [CustomerController::class, 'setAddressPrimary']); | |
| 60 | 61 | }); |
| 61 | 62 | |
| 62 | 63 | $router->prefix('customer-profile')->withPolicy('CustomerFrontendPolicy')->group(function (Router $router) { |
| 63 | 64 | $router->get('/', [CustomerProfileController::class, 'index']); |
| @@ -63,8 +64,9 @@ | ||
| 63 | 64 | $router->get('/', [CustomerProfileController::class, 'index']); |
| 64 | 65 | $router->get('/downloads', [CustomerProfileController::class, 'getDownloads']); |
| 65 | 66 | |
| 66 | 67 | $router->get('/profile', [CustomerProfileController::class, 'getCustomerProfileDetails']); |
| 68 | + $router->get('/sections', [CustomerProfileController::class, 'getSections']); | |
| 67 | 69 | $router->post('/create-address', [CustomerProfileController::class, 'createCustomerProfileAddress']); |
| 68 | 70 | |
| 69 | 71 | $router->post('/edit-address', [CustomerProfileController::class, 'updateCustomerProfileAddress']); |
| 70 | 72 | $router->post('/make-primary-address', [CustomerProfileController::class, 'makePrimaryCustomerProfileAddress']); |
| @@ -92,6 +94,22 @@ | ||
| 92 | 94 | $router->post('subscriptions/{subscription_uuid}/switch-payment-method', [CustomerSubscriptionController::class, 'switchPaymentMethod'])->alphaNumDash('subscription_uuid'); |
| 93 | 95 | $router->post('subscriptions/{subscription_uuid}/confirm-subscription-switch', [CustomerSubscriptionController::class, 'confirmSubscriptionSwitch'])->alphaNumDash('subscription_uuid'); |
| 94 | 96 | $router->post('subscriptions/{subscription_uuid}/cancel-auto-renew', [CustomerSubscriptionController::class, 'cancelAutoRenew'])->alphaNumDash('subscription_uuid'); |
| 95 | 97 | $router->post('subscriptions/{subscription_uuid}/initiate-early-payment', [CustomerSubscriptionController::class, 'initiateEarlyPayment'])->alphaNumDash('subscription_uuid'); |
| 98 | + $router->post('subscriptions/{subscription_uuid}/pause', [CustomerSubscriptionController::class, 'pauseSubscription'])->alphaNumDash('subscription_uuid'); | |
| 99 | + $router->post('subscriptions/{subscription_uuid}/resume', [CustomerSubscriptionController::class, 'resumeSubscription'])->alphaNumDash('subscription_uuid'); | |
| 96 | 100 | |
| 101 | + // my reviews — type=pending returns the to-be-reviewed products | |
| 102 | + $router->get('reviews', [ProductReviewFrontendController::class, 'getReviewsByCustomer']); | |
| 103 | + $router->get('reviews/submission-form', [ProductReviewFrontendController::class, 'getReviewSubmissionForm']); | |
| 97 | 104 | }); |
| 105 | + | |
| 106 | +// Public product reviews routes | |
| 107 | +$router->prefix('public/reviews') | |
| 108 | + ->withPolicy('PublicPolicy')->group(function (Router $router) { | |
| 109 | + $router->get('/{postId}', [ProductReviewFrontendController::class, 'getReviews'])->int('postId'); | |
| 110 | + $router->get('/{postId}/summary', [ProductReviewFrontendController::class, 'getRatingSummary'])->int('postId'); | |
| 111 | + $router->post('/{postId}', [ProductReviewFrontendController::class, 'submitReview'])->int('postId'); | |
| 112 | + $router->put('/{postId}/{reviewId}', [ProductReviewFrontendController::class, 'updateReview'])->int('postId')->int('reviewId'); | |
| 113 | + $router->get('/{postId}/{reviewId}/replies', [ProductReviewFrontendController::class, 'getReplies'])->int('postId')->int('reviewId'); | |
| 114 | + $router->get('/{postId}/{reviewId}/modal', [ProductReviewFrontendController::class, 'getModalView'])->int('postId')->int('reviewId'); | |
| 115 | + }); | |