Saved filters

View on GitHub

Saved filters

A SavedFilter is a named, stored combination of search/label/status/ priority/assignee query params for a project (the priority param holds priority ids, e.g. 1,3, not names — deleting a priority drops its id from the project's saved filters, see ../priorities/README.mdPrioritiesAn issue's priority is a per-project resource backed by a real priorities database table (App\Models\Priority) — not the fixed low / medium / high enum it…), created from useSavedFilters()'s saveFilter(name, queryParams) and listed back via Project::savedFilters(). This category documents two real gaps found while researching it: the Controller bypasses the Service layer entirely (see ../activity-log/01-log-a-new-kind-of-activity.mdActivity logLog a new kind of activityThere's no enum, no registration step, no frontend map to update — logging a new kind of activity is a single method call, wherever the action already happ…, which already introduces the missing SavedFilterService as its worked example), and the context column is written on every save but never actually read anywhere — every saved filter shows up regardless of which view (List/Board/Calendar) it was saved from.

Guides, in the order you'd actually need them

  1. Extract the Service layerSaved filtersExtract the Service layerSavedFilterController is the one Controller in the app that constructs and deletes an Eloquent model directly, bypassing the Controller → Service → Reposit… — the same SavedFilterService introduced in ../activity-log/01-log-a-new-kind-of-activity.mdActivity logLog a new kind of activityThere's no enum, no registration step, no frontend map to update — logging a new kind of activity is a single method call, wherever the action already happ…, covered here in full (both create() and delete(), plus the Controller/route/test changes) since this category is where it actually belongs.
  2. Make context actually scope which filters showSaved filtersMake `context` actually scope which filters showToday, context is stored (as project${projectId} ) but never read back — Pages/Projects/Show.tsx passes the entire savedFilters array to FilterBar regardle… — worked example fixing the second gap: filtering the saved-filter list by the active view's context instead of showing every saved filter for the project everywhere.

The architecture in one paragraph

SavedFilter (project_id, name, context, query_params — the last cast to array) has no dedicated Policy; both SavedFilterController::store()/destroy() authorize only against view on the project (Project::savedFilters()'s parent), so any member can create or delete any saved filter belonging to a project they're in — there's no per-filter ownership concept today, unlike comments'Roles & permissions (RBAC)Every project has its own role-based access control: four built-in system role tiers (Owner, Admin, Member, Viewer) plus any number of project-defined cust… own/any distinction. On the frontend, useSavedFilters() computes context as `project_${projectId}` whenever a projectId is given, and refuses to save at all (logging to the console, not surfacing a user -facing error) when one isn't — meaning the hook's own fallback context value, the literal string 'project_issues', is never actually sent to the server by any real call site today, since reaching that branch requires not having a projectId, which the very next line turns into an early return. context is stored faithfully either way, but nothing on the frontend currently reads or filters by it when listing saved filters back — see guide 2.