Skip to content

Attendance feature#215

Merged
toomuchpete merged 23 commits into
masterfrom
attendance-feature
May 5, 2026
Merged

Attendance feature#215
toomuchpete merged 23 commits into
masterfrom
attendance-feature

Conversation

@toomuchpete
Copy link
Copy Markdown
Member

No description provided.

toomuchpete and others added 23 commits May 4, 2026 21:45
Replaces captain-run GroupMe attendance polls with an in-app SMS/email/web
RSVP system, per-game-day, with captain and commissioner dashboards.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
- §4: rewrite parser as dispatch-mediated; define "active pending" scope
  explicitly; clarify that AttendancePromptDispatch.prompts is load-bearing
  for lookup, not just an audit trail.
- §6: add active_pending and convenience scopes so the dependency from §4 is
  visible in the data model.
- §2: clarify channel resolution; document email opt-out semantics; document
  multi-target send behavior; call out SMS/email asymmetry as deliberate.
- §9: document STOP as an all-or-nothing carrier-level block affecting all
  AFDC SMS, not attendance pings only.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
15 tasks covering schema, models, services, worker, mailer, controller,
captain dashboard, commissioner overview, per-league flag UI, and
end-to-end integration. Each task is a single sane commit.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
…anch.

Past-Pete's prototype on origin/attendance_tracker is architecturally
incompatible (Twilio Studio dependency) but had product-surface ideas worth
folding in:

- Gender-split Yes/No/Not Answered counts on captain and commissioner
  dashboards (essential for ultimate's gendered roster ratios).
- Inline display of accepted PickupRegistration entries on dashboards
  (captains care about headcount including pickups, not just roster).
- New Task 12: captain bulk-update view for marking many players at once.
- Switch Task 9 to a dedicated AttendanceMailer class (matches existing
  per-domain mailer pattern).
- "(ACTION REQUIRED)" suffix in email subject for open-rate.
- Uniqueness validation on (user, team, game_day).
- New Task 17: attendance:preview and attendance:run_now rake tasks for
  ops dry-runs during initial rollout.

Architectural decisions in the spec (no Twilio Studio, dispatch-mediated
parser, all-or-nothing STOP) are unchanged.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
…default.

Test config previously hardcoded 'mongodb:27017' (a docker-compose service
name), preventing rspec from running outside Docker. Now reads
TEST_MONGO_HOST with localhost as the default — backward-compatible with
docker-compose runs (set TEST_MONGO_HOST=mongodb) and works out of the box
for local rspec.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
The mailer is built alongside the dispatcher because the dispatcher's email
path calls AttendanceMailer.attendance_prompt directly; isolating them into
separate commits would require an interim stub.

Mailer subject uses the (ACTION REQUIRED) suffix style. Email view
references rsvp_url, which depends on the route added in the
AttendancePromptsController task.
…inder cadence

Includes a class-level .preview helper for ops dry-runs.

Test infrastructure changes:
- Run Sidekiq inline in tests so perform_async doesn't require Redis.
- Drop the Mongo session before each spec to prevent state leak across tests.
Patches Rails 4.2 + Ruby 2.6 controller-test ThreadError in spec_helper.
Captain dashboard shows per-game-day attendance with gender-split counts
and inline display of accepted pickup registrations. Per-row override path
plus a bulk-update view for marking many players at once.
When the env var is set to a comma-separated list of emails, the dispatcher
only sends SMS/email to users whose email is in the list. Prompt records
are still created upstream by the worker so the captain dashboard reflects
real state. Designed to be removed before GA — search for 'TRIAL — REMOVE
BEFORE GA' to find both the guard and its helper.
Production already configures config.action_mailer.default_url_options =
{ host: 'leagues.afdc.com' } in production.rb. There's no reason to invent
a parallel env var.

- Mailer helper now calls attendance_token_url(token: t) directly; mailer
  views auto-pick up the configured host.
- SMS auto-reply in the controller uses request.host.
- Test env gets default_url_options = { host: 'test.example.com' } (the
  test env didn't have one before, which is why the new spec needed it).
- Adds the AttendanceMailer spec that was missing from the original
  build (the dispatcher spec covered the path indirectly via mocks).
Local rspec defaults TEST_MONGO_HOST to 'localhost' (set in mongoid.yml).
The docker-compose test container needs to override this to the mongo
service name so the SUT container can reach Mongo at the docker network
hostname. Pairs with the prior commit that introduced the env-var-based
test mongo host.
The initializer was unconditionally assigning ENV['secret_token'] and
ENV['secret_key_base']. When those env vars are unset (as in the Docker
test container), the initializer overwrites whatever was set in
environments/*.rb with nil — leading to the cryptic 'Missing secret_token
and secret_key_base' error from controller specs.

- Guard the initializer on env-var presence so it only sets values it has.
- Add a test-env secret_key_base alongside the existing secret_token.

The bug was latent until our new controller specs first exercised the
secret-validating code path.
@toomuchpete toomuchpete merged commit b425025 into master May 5, 2026
3 checks passed
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