saucebase-dev/roadmap/saucebase-roadmap-development
Claude Code and agent skill by saucebase-dev/roadmap
- community
Checking that the SKILL.md file is still in the repository.
Work on the Roadmap module (modules/roadmap) — public feature board, upvotes, comments, moderation statuses, duplicate merging, notifications, and its Filament admin. Use when changing roadmap pages, routes, models, or tests.
Install
npx vskill@latest install saucebase-dev/roadmap/saucebase-roadmap-developmentSKILL.md
Roadmap Module
Paths are relative to modules/roadmap/ unless they say otherwise. Commands run from the application root.
Overview
Public roadmap board with feature requests, upvotes, comments, team replies, and duplicate merging. Filament admin at /admin → Roadmap. Modules\Roadmap\Filament\Widgets\RoadmapAttentionWidget puts "Suggestions to review" (status Under Review) on the dashboard, sort 21, only while there are any.
Non-Obvious Design
Admin Permission
One permission, manage roadmap, covers the whole admin area: RoadmapItemResource, RoadmapCommentResource and the RoadmapSettings page check it in canAccess(). access admin panel alone only opens the panel. Database\Seeders\DatabaseSeeder creates it, granted to nobody; the app's roles seeder decides who gets it, and admin passes every check.
Statuses Split Moderation From Stage
RoadmapStatus mixes two jobs on purpose, and three helpers decide what shows where:
- Hidden from visitors:
UnderReview(where every suggestion lands) andClosed(rejected, cancelled, or merged away). - `publicStatuses()` — what a visitor may read, vote on, and comment on:
Backlog,Planned,InProgress,Shipped. - `boardStatuses()` — the three board columns:
Planned,InProgress,Shipped.Backlogis public but deliberately off the board, listed underneath it.
Every read and write path checks RoadmapItem::isPublic() and 404s otherwise. Adding a status means deciding which of those two lists it belongs to.
One exception, in RoadmapItemPolicy::view(): an item's author can open their own item whatever its status, because "My feedback" lists and links it, and so can anyone with manage roadmap. The page is read-only then: the payload's votable is false, which disables the vote button, and comments_enabled is false. The vote and comment routes still 404. The page answers 404 on a refusal, never 403, which would confirm the item exists.
A Vote Row Is An Upvote
There are no downvotes and no vote type column. A row in roadmap_votes means "this user wants this", and voting again deletes the row. The unique index on (roadmap_item_id, user_id) is what keeps one vote per person.
Submitting an item also creates that person's vote, so nothing sits at zero.
Writes go through src/Actions/: SubmitSuggestion, ToggleVote and MergeItem. ToggleVote takes no lock: a double click that inserts the same vote twice trips the unique index, which the action treats as already voted.
Public Page, Optional Login
roadmap.index and roadmap.show are outside the auth middleware — they are the marketing surface and are in the sitemap. Voting, commenting, and suggesting are inside auth and verified (roadmap.vote, roadmap.comments.store, roadmap.store); verified only acts once the app's User implements MustVerifyEmail (sc-1134). Both pages send an authenticated prop so the frontend sends guests to login instead of hiding the buttons.
Page Or Slideover, Same URL
RoadmapController::show() returns Inertia::modal(...) when the request carries Modal::HEADER_MODAL, and an ordinary Inertia::render(...) otherwise. The board opens items in a right-hand slideover through ModalLink; a typed or shared link renders the full page, which is what search engines and the sitemap need.
Decide on the header, never the referer: the package would otherwise treat any in-app link as "open me over the previous page". ItemDetail holds the markup for both so they cannot drift.
Posting a comment inside the slideover redirects the page behind it, so the form calls modal.reload() when useModal() returns a modal, and router.reload({ only: ['item'] }) when it does not.
Hidden Comments
Moderation hides rather than deletes: hidden_at plus a private hidden_reason. comments() is every comment, visibleComments() is the public one, and both the payload and comments_count use the latter. A hidden comment stays in the database for the admin and never reaches the page.
RoadmapSettings::comments_enabled switches comments off entirely; the controller 404s on post, so hiding the UI is not the only defence.
Merging Duplicates
Actions\MergeItem moves votes and comments to the target, drops votes from anyone who had voted on both (the unique index would reject them), then sets merged_into_id and closes the source. comments()->reorder() matters: the relation is ordered, and an ordered UPDATE is not portable.
Notifications Go To Everyone Waiting
StatusChanged dispatches after commit, so a rolled-back merge mails nobody, and the mail itself is queued. A status change notifies subscribers(): the submitter plus everyone who voted. Voting is how you subscribe.
Mail lines are rendered as Markdown, so the item title is escaped before interpolation — otherwise a title could put a working link into someone's inbox. HTML is already escaped by the mail view; Markdown link syntax is not.
Rate Limits Are Named, With Two Windows
RoadmapServiceProvider::registerRateLimits() defines roadmap-suggest, roadmap-comment, and roadmap-vote. Each write route has a burst limit and a slower one behind it, because a per-minute limit alone still allows a steady drip all day. Keyed by user id, falling back to IP.
Dates
Comments and responses are sent as ISO strings and formatted with the app's formatDate() (@saucebase/core/lib/dates), which formats in UTC, so the server render and every browser agree on the day.
Testing
Security
- Security scanPassed, 90 of 100Pattern checks on the skill's files.
- Model reviewPassed
Quality evaluation
- Task evaluationNot runNo evaluation yet. Run one in Skill Studio.
Source
- SKILL.md in the repositoryCheckingresources/boost/skills/saucebase-roadmap-development/SKILL.md
Popularity
- Repository stars
- 1
- 7-day trend score
- 0
Stars and forks are for the whole GitHub repository, not this skill alone. Not refreshed yet.
Works with
Any agent vskill installs to: 56 targets in all. These 39 have a page on this site.
- Claude Code
- Cursor
- GitHub Copilot
- Windsurf
- Codex
- Gemini CLI
- Cline
- Amp
- Roo Code
- Goose
- Continue
- Kilo Code
- Junie
- Trae
- OpenHands
- Qwen Code
- AI Agent
- Tabnine Chat
- Sourcegraph Cody
- Amazon Q
- Firebase Genkit
- Sweep
- Devin
- Phind
- Mentat
- Claude Desktop
- Aider
- GPT Pilot
- Plandex
- bolt.new
- v0
- Replit Agent
- Anse
- TypingMind
- BetterChatGPT
- LibreChat
- Warp AI
- Pieces
- Fig AI
Embed badge
[](https://verified-skill.com/skills/saucebase-dev/roadmap/saucebase-roadmap-development)