Skip to content

Station signup: jobs/station-signup-review for the pending digest and 30-day downgrade #2364

Description

@jakebromberg

Problem

Manager review is manual, and this station has a documented history of limbo states going unnoticed — a migration backfill predicate drift stranded ~17 DJs at /login?incomplete=true until someone noticed (#1451 lineage). "A manager will review it" is not a safe assumption, and the whole point of this feature is that it runs during weeks when nobody is watching.

Without this job, a self-signed account keeps dj — and flowsheet write access — indefinitely if the queue is ignored.

Desired end state

A jobs/station-signup-review workspace doing two things daily:

  1. Digest — while any accounts are pending, email a summary to STATION_SIGNUP_ALERT_EMAIL. Follow jobs/metadata-no-match-digest/ as the template, including resolveDigestRecipient()'s shape in its email.ts and the EMAIL_ENABLED kill switch.
  2. Downgrade — accounts pending review for more than 30 days drop dj -> member. Reversible with one roster edit; never deletes, never bans.

Both live in one workspace because they read the same rows, which lets the digest name the accounts about to be downgraded rather than re-deriving the other job's cutoff.

Why 30 days: it exceeds any holiday break, so it cannot fire mid-break and strand a working DJ. It only ever catches accounts nobody reviewed after the break ended.

The downgrade write path

Write auth_member.role directly via @wxyc/database, as jobs do. This is safe for this specific pair because grantsAdminFlag is normalizeRole(role) === 'stationManager', so neither dj nor member touches the auth_user.role='admin' flag and no hook needs to fire.

State that invariant in the job. Reusing this path for a different role pair would desync the admin flag silently. See #2171 for the standing auth_user.role / auth_member.role drift this relies on not making worse.

Recipient

STATION_SIGNUP_ALERT_EMAIL, pointed at a station alias rather than a personal inbox — this feature exists for weeks when individuals are away. Mirrors DIGEST_RECIPIENT_EMAIL in jobs/metadata-no-match-digest/email.ts.

Cron registration

docs/ops-cron-scheduling.md under "Excluded / DB-only" (line 46), not the LML slot table.

Acceptance criteria

  • Workspace with the full jobs/* footprint (see jobs/flowsheet-ghost-row-sweep/)
  • Digest sends only when something is pending; honours EMAIL_ENABLED
  • Downgrade fires at 30 days, is reversible, never deletes or bans
  • Downgrade leaves auth_user.role untouched, with a test pinning the invariant
  • STATION_SIGNUP_ALERT_EMAIL documented in docs/env-vars.md
  • Registered in the DB-only cron section

Context

Plan: ~/Downloads/wxyc-station-passcode-signup-plan.md.

Related

Blocked by the schema issue.

Blocked by

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    enhancementNew feature or request

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions