4.6 KiB
4.6 KiB
name, description
| name | description |
|---|---|
| project-route-structure | Always apply in this project when creating, moving, or refactoring Laravel route definitions in routes/**/*.php; changing route prefixes, names, middleware, scoped bindings, or route files; or adding frontend-facing endpoints that Wayfinder generates. Documents the KanbanGit route-file layout and grouping conventions. |
Project Route Structure
When to Apply
Activate this skill whenever work in this project changes:
routes/**/*.php- Route names, URI prefixes, middleware groups, scoped bindings, or controller route registrations
- Frontend-facing endpoints that require regenerated Wayfinder output
Use this together with laravel-best-practices. Also activate wayfinder-development when route changes affect generated frontend route/action imports.
Route Files
routes/web.phpis the web entry point only. Keep public shell routes here, such ashomeanddashboard, then require domain route files.routes/web/projects.phpowns the mainprojects.*structure.routes/web/admin.phpowns alladmin.*routes.routes/web/teams.phpowns allteams.*routes.routes/web/settings.phpowns account settings routes, but keeps their existing route names such asprofile.edit,security.edit, andgit-connections.edit.routes/web/project/*.phpcontains larger nested project route sections that would makeroutes/web/projects.phptoo deeply indented.
Add a new route file only when a domain gets large enough to stand alone. Otherwise, extend the existing domain file.
Grouping Pattern
- Put shared middleware, URI prefixes, route name prefixes, and controller declarations on groups instead of repeating them on each route.
- Prefer this nesting order when it reads naturally:
middleware(...),prefix(...),name(...),controller(...), thengroup(...). - Keep public route names stable unless the user explicitly asks for a public interface change.
- Keep route URIs stable when reorganizing route files; this kind of change should be structural.
- Use
function (): voidfor route group closures. - For large nested sections, keep the structural group in the parent file and
requirea child file from inside the group. For example, keepRoute::prefix('tickets')->name('tickets.')->group(...)inroutes/web/projects.php, then requireroutes/web/project/tickets.phpinside it.
Project Routes
Project routes should follow this shape:
- Top-level group:
middleware(['auth', 'verified']),prefix('projects'),name('projects.'). - Project create/store routes live under
can:create-project. - Routes under
{project}use project gates by capability:- Read pages:
can:view-project,project - Mutations:
can:write-project,project - Project settings and access management:
can:admin-project,project - Project delete:
can:access-admin
- Read pages:
projects/{project}/permissions/...must not be insideRoute::scopeBindings(), becauseProjectdoes not defineusers()orteams()child relationships.- Use
Route::scopeBindings()only around nested project resources that should bind through project-owned relationships, such as tickets and project settings children. - Keep the outer
{project}group inroutes/web/projects.php; it is part of the main project structure. - Keep compact view routes, such as show, board, and backlog, directly in
routes/web/projects.php. - Keep ticket subroutes grouped under
tickets.inroutes/web/projects.php, with the route contents inroutes/web/project/tickets.php. - Keep settings subroutes grouped under
settings.inroutes/web/projects.php, with the route contents inroutes/web/project/settings.php. - Split dense settings subsections further under
routes/web/project/settings/, such asboard.php,metadata.php, andrepositories.php.
Settings Routes
- Keep the
settingsURI prefix grouped. - Keep profile edit/update behind
authonly. - Keep profile deletion, security, git connections, and appearance behind
authplusverified. - Do not rename settings routes to a
settings.*namespace unless the frontend/tests are intentionally updated.
Verification
After changing route files:
- Run
php artisan route:list --except-vendor. - Run
php artisan wayfinder:generate --with-form --no-interactionwhen any route signature, name, method, or controller action changed. - Run
vendor/bin/pint --dirty --format agentfor PHP route formatting. - Run the affected feature tests, usually
php artisan test --compact tests/Feature/Projects tests/Feature/Teams tests/Feature/Admin tests/Feature/Settings. - Run
git diff --checkbefore finalizing.