Replace full previous_url query parameters with a short nav token and keep navigation history in session. This must:
Location headers on redirects.In URL:
?nav=abc123xyz
In session:
[
'navigation' => [
'abc123xyz' => [
'updated_at' => 1713945600,
'stack' => [
'/reclamations?filters[comment]=...',
'/reclamations/show/848',
'/catalog/show/15',
],
],
],
]
nav in links and forms.previous_url in redirects again.Create:
app/Services/NavigationContextService.phpResponsibilities:
Planned public API:
getOrCreateToken(Request $request): string
rememberCurrentPage(Request $request, string $token): void
backUrl(Request $request, string $token, ?string $fallback = null): ?string
routeParams(array $params, string $token): array
pruneExpired(): void
forgetToken(string $token): void
Internal helpers:
normalizeUrl(string $url): string
isGetPage(Request $request): bool
context(string $token): array
saveContext(string $token, array $context): void
Rules for session history:
nav;updated_at.Requirements:
Recommended format:
bin2hex(random_bytes(8))
Current base methods:
resolvePreviousUrl()previousUrlForRedirect()Add wrappers over the new service:
resolveNavToken(Request $request): stringrememberNavigation(Request $request, string $token): voidnavigationBackUrl(Request $request, string $token, ?string $fallback = null): ?stringwithNav(array $params, string $token): arrayFor transition period, do not remove old methods immediately.
If token is missing or stack is empty, each module needs a stable fallback.
Initial list:
route('reclamations.index', session('gp_reclamations'))route('order.index', session('gp_orders'))route('spare_parts.index')route('spare_part_orders.index')route('import.index', session('gp_import'))Need to confirm catalog/product fallback if dedicated index route exists.
backUrl() must return previous page relative to current page, not just latest entry.
If stack is:
/reclamations?filters=...
/reclamations/show/848
/catalog/show/15
Then on /catalog/show/15 back URL must be /reclamations/show/848.
Algorithm:
Start with pages that render show/edit screens and need back navigation.
Priority controllers:
ReclamationController@showOrderController@show, @editProductController@show/editProductSKUController@show/editSparePartController@show/editSparePartOrderController@show/editImportController@showPattern for each GET action:
$nav = $this->resolveNavToken($request);
$this->rememberNavigation($request, $nav);
$this->data['nav'] = $nav;
$this->data['back_url'] = $this->navigationBackUrl(
$request,
$nav,
route('reclamations.index', session('gp_reclamations'))
);
previous_url in Blade LinksMain rule:
previous_url;nav.Highest-risk files:
resources/views/partials/table.blade.phpresources/views/orders/show.blade.phpresources/views/reclamations/edit.blade.phpresources/views/catalog/edit.blade.phpresources/views/products_sku/edit.blade.phpresources/views/spare_parts/edit.blade.phpresources/views/spare_part_orders/edit.blade.phpExpected view variables:
$nav$back_urlButtons/links:
$back_url for "Назад";route(..., ['nav' => $nav]) for nested transitions.previous_url in Forms and AJAXHidden fields:
previous_url with hidden nav.AJAX updates:
nav;previous_url;204 No Content for AJAX updates where page refresh is not needed.This is especially relevant for:
resources/views/reclamations/edit.blade.phpMain rule:
nav;nav, or to resolved back URL;previous_url must not appear in redirect params.High-priority controllers:
ReclamationControllerProductControllerOrderControllerProductSKUControllerSparePartControllerSparePartOrderControllerPattern:
$nav = $request->string('nav')->toString();
return redirect()->route('reclamations.show', [
'reclamation' => $reclamation,
'nav' => $nav,
]);
Use redirect()->to($backUrl) only when action should return to parent page instead of current card.
For rollout safety:
nav exists, use new logic.nav is missing but previous_url exists:
previous_url as first stack item;This allows gradual migration without breaking old entry points.
Review and update shared templates:
resources/views/partials/submit.blade.phpresources/views/partials/table.blade.phpTarget:
$back_url instead of $previous_url;$nav instead of embedding source URL directly.url()->previous() should remain only as a last-resort fallback if needed.
To prevent session growth:
Cleanup should run inside service on:
getOrCreateToken()rememberCurrentPage()Add feature tests for:
nav absent;nav present;nav removed during URL normalization;list -> show back navigation;list -> reclamation -> catalog nested back navigation;nav tokens do not conflict;previous_url;204 and no Location.NavigationContextService;Controller;ReclamationController;resources/views/reclamations/edit.blade.php;resources/views/partials/table.blade.php;OrderController;resources/views/orders/show.blade.php.ProductController;ProductSKUController;resources/views/catalog/edit.blade.phpresources/views/products_sku/edit.blade.phpSparePartController;SparePartOrderController;previous_url from links and hidden inputs;resolvePreviousUrl() and previousUrlForRedirect().Mixed old/new navigation while migration is incomplete
Mitigation: transitional compatibility
Reusing one token across unrelated flows
Mitigation: create token only at chain entry, then pass it through
Cyclic or noisy back navigation
Mitigation: normalize URLs and deduplicate stack
Wrong fallback target
Mitigation: define fallback per module instead of global fallback
Task is done when:
previous_url is no longer passed in links and redirects;nav is used in key transitions;reclamations list -> reclamation -> catalog -> skuLocation headers.