Skip to content

Add audience field for role-restricted event visibility#22

Open
Kitkatnik wants to merge 2 commits intomainfrom
Kitkatnik/event-audience
Open

Add audience field for role-restricted event visibility#22
Kitkatnik wants to merge 2 commits intomainfrom
Kitkatnik/event-audience

Conversation

@Kitkatnik
Copy link
Copy Markdown
Collaborator

Summary

  • Adds an audience enum to ScheduleItem (everyone default, volunteers_only) layered on top of is_public, so admins can publish events that only volunteers and admins see on /schedule. Visibility is enforced in two places via a new ScheduleItem.visible_to(user) scope: the public schedule list AND PlanItemsController#create (so attendees can't bypass the list and RSVP to a hidden event by guessing the ID).
  • Admin form gets a "Visible to" select; admin index shows a small "(volunteers)" indicator next to the Public badge. The user-facing /schedule_items form is intentionally untouched — attendee-created activities default to audience: "everyone" via the column default.
  • Includes 13 new tests across the model scope, admin controller permitted-params, /schedule integration, and the PlanItemsController 404 guard.

Test plan

  • bin/rails test — 120 runs, 326 assertions, 0 failures
  • bin/rubocop, bin/brakeman, bin/bundler-audit, bin/importmap audit — all clean
  • Manual: as admin, create a public volunteers_only event; confirm it appears on /schedule for admin + volunteer, hidden for attendee
  • Manual: as attendee, attempt POST to /plan_items with a hidden event's ID — expect 404
  • Manual: plan an everyone event as attendee, then admin flips it to volunteers_only — confirm it stays on attendee's /plan (grandfather behavior)

Admins can now mark a public event as visible only to volunteers and
admins. Use case: a volunteer briefing or staff-only coordination
session that should appear on /schedule for the right roles but stay
completely invisible to regular attendees.

Data model: a string-backed `audience` enum on ScheduleItem with two
values, "everyone" (default, current behavior) and "volunteers_only".
The field only matters when is_public: true; private events stay
admin-only as before.

Visibility rules (ScheduleItem.visible_to(user) scope):
- admin / volunteer: sees all public items regardless of audience
- attendee / signed-out: sees only items with audience: "everyone"
- private items (is_public: false): never appear, for any role

Wired into both read paths:
- ScheduleController#index — list filter on /schedule
- PlanItemsController#create — security guard so an attendee cannot
  bypass the list and RSVP to a hidden event by guessing its ID

Admin UI:
- New "Visible to" select on the admin schedule-item form, below the
  Public checkbox. Two options: Everyone / Volunteers only.
- Admin index now shows "(volunteers)" next to the Public badge when
  audience is restricted, so the audience is visible at a glance.

Out of scope (deferred):
- Per-user invitee picker — interview confirmed roles are sufficient.
- Audience selection on the user-facing /schedule_items form. Attendee-
  created activities default to audience: "everyone" via the column
  default.
- Adding "admins_only" as a third audience — one-line follow-up if ever
  needed.

Existing :public_items scope is preserved; :visible_to composes on top.
Existing plan items are grandfathered: changing audience after a user
plans an event does not retroactively remove it from their /plan.
@railway-app
Copy link
Copy Markdown

railway-app Bot commented Apr 26, 2026

🚅 Deployed to the ruby-embassy-pr-22 environment in ruby-embassy

Service Status Web Updated (UTC)
ruby-embassy 🚨 Crashed (View Logs) Web Apr 26, 2026 at 7:04 am

@railway-app railway-app Bot temporarily deployed to ruby-embassy / ruby-embassy-pr-22 April 26, 2026 06:44 Destroyed
# Conflicts:
#	app/controllers/admin/schedule_items_controller.rb
#	db/schema.rb
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant