Files
KanbanGit/.agents/skills/project-route-structure/SKILL.md
T

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.php is the web entry point only. Keep public shell routes here, such as home and dashboard, then require domain route files.
  • routes/web/projects.php owns the main projects.* structure.
  • routes/web/admin.php owns all admin.* routes.
  • routes/web/teams.php owns all teams.* routes.
  • routes/web/settings.php owns account settings routes, but keeps their existing route names such as profile.edit, security.edit, and git-connections.edit.
  • routes/web/project/*.php contains larger nested project route sections that would make routes/web/projects.php too 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(...), then group(...).
  • 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 (): void for route group closures.
  • For large nested sections, keep the structural group in the parent file and require a child file from inside the group. For example, keep Route::prefix('tickets')->name('tickets.')->group(...) in routes/web/projects.php, then require routes/web/project/tickets.php inside 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
  • projects/{project}/permissions/... must not be inside Route::scopeBindings(), because Project does not define users() or teams() 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 in routes/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. in routes/web/projects.php, with the route contents in routes/web/project/tickets.php.
  • Keep settings subroutes grouped under settings. in routes/web/projects.php, with the route contents in routes/web/project/settings.php.
  • Split dense settings subsections further under routes/web/project/settings/, such as board.php, metadata.php, and repositories.php.

Settings Routes

  • Keep the settings URI prefix grouped.
  • Keep profile edit/update behind auth only.
  • Keep profile deletion, security, git connections, and appearance behind auth plus verified.
  • Do not rename settings routes to a settings.* namespace unless the frontend/tests are intentionally updated.

Verification

After changing route files:

  1. Run php artisan route:list --except-vendor.
  2. Run php artisan wayfinder:generate --with-form --no-interaction when any route signature, name, method, or controller action changed.
  3. Run vendor/bin/pint --dirty --format agent for PHP route formatting.
  4. Run the affected feature tests, usually php artisan test --compact tests/Feature/Projects tests/Feature/Teams tests/Feature/Admin tests/Feature/Settings.
  5. Run git diff --check before finalizing.