Signup nudge eligibility treats subscribed-then-unsubscribed members as never subscribed
Los mantenedores suelen responder en 1 día
Nadie ha tomado este issue todavía.
Evaluación
- Dificultad
- 5/5
- Tiempo estimado
- Más de una semana
- Aptitud para principiantes
- 35/100
Línea de trabajo
Start with app/services/signup_nudge_email_service.rb#never_subscribed and app/controllers/subscriptions_controller.rb#destroy, then inspect the subscription and activity data model. Confirm which persistence direction maintainers choose before implementing it. Done means a member who subscribed and later unsubscribed is not treated as never subscribed, while group-specific eligibility and followup behavior remain correct.
Escrito por el modelo de indexación a partir del texto del issue.
Descripción
Summary
SignupNudgeEmailService#never_subscribed defines eligibility as "has no row in subscriptions". But SubscriptionsController#destroy deletes the subscription row when a member unsubscribes from a chapter group. A member who subscribed and later left is therefore indistinguishable from a member who never subscribed at all — and becomes nudge-eligible again.
Real production case
Member 31302 (dump of 2026-09-24), full timeline from activities + workshop_invitations:
| Time (2026-09, UTC) | Event |
|---|---|
| 09-02 11:16 | Signs up |
| 09-02 11:18 | RSVPs as Coach (2 minutes after signup) |
| 09-09 18:30 | Attends London workshop |
| 09-17 09:16 | RSVPs to the next London workshop |
| 09-17 09:34 | Unsubscribes from London Coaches group (subscription.removed activity, id 569) |
| 09-17 13:04 | Receives a "Let's get you connected with codebar!" signup nudge |
Four hours after choosing to leave the chapter group, this actively engaged coach got an email whose premise is "you never connected with codebar". The unsubscribe made him eligible again; the nudge arrived same-day.
Two compounding facts:
subscription.createdactivity tracking only started 2026-09-13 (65 events / 41 members) andsubscription.removedon 2026-09-14 (61 events / 45 members). His subscription predates tracking, so its removal left no "was subscribed" evidence — only the removal event exists.- In the dump, 37 of the 45 members with a tracked unsubscribe now have zero subscription rows — i.e. the nudge service currently classifies all 37 as "never subscribed". One of them is inside the current nudge window and not banned.
Why this is separate from #2919
The daily duplicate-send bug (#2919, .merge clobbering the delivery anti-join) causes the same member to be emailed repeatedly, but fixing it does not fix this: a subscribe-then-unsubscribe member with no prior nudge is genuinely selected by the corrected query. The eligibility rule itself needs to account for unsubscribes.
Scope of the wrongness
- Messaging mismatch: the nudge copy assumes a dormant lurker; unsubscribers made an active choice to leave. Re-pitching them risks reading as ignoring their opt-out.
- Same-day turnarounds are possible for any churn event shortly before the daily 12:00 UTC run, as the timeline shows.
- The unsubscribe may have been from one group only (e.g. left Coaches, still interested in Students) — naive "any unsubscribe = never eligible" would over-correct. Today's schema can't tell, because the row is gone.
Possible directions (for discussion)
- Tombstone subscriptions — soft-delete/discards (
discarded_at) or astatecolumn, so history survives; eligibility then reads "never had an active subscription". Most robust; biggest change. - Eligibility excludes members with a
subscription.removedactivity — cheap, but blind to all pre-2026-09-13 subscriptions, and depends on activity rows never being cleaned (nothing prunesactivitiestoday, but nothing guarantees that). - Member-level flag set on unsubscribe (mirroring the
received_student/coach_welcome_emailpattern) — simple, but loses which group/chapter was left.
Happy to take whichever direction maintainers prefer; option 1 is the only one that also preserves the data for the followup email logic (which keys off member_email_deliveries.created_at and would otherwise send a followup to someone who already left).
Environment
app/services/signup_nudge_email_service.rb(never_subscribed) andapp/controllers/subscriptions_controller.rb#destroyata50b5214- Rails 8.1 / Ruby 4.0, verified against
codebar_production_dump2026-09-24
- Lenguaje dominante
- Ruby
- Estrellas
- 104
- Forks
- 205
- Merge medio
- 1 d 2 h
- PR fusionados (30 d)
- 77
Preparar el entorno
- Incluye un Dockerfile o un archivo de Docker Compose
- Sin plantilla de pull request
- Leer la guía de contribución
Primeros pasos
- Lee el issue completo y luego la guía de contribución del proyecto.
- Comenta en el issue que vas a ocuparte — evita que dos personas hagan lo mismo.
- Haz un fork del repositorio y trabaja en una rama.
- Abre un pull request que haga referencia al número del issue.
Más de codebar/planner
-
enhancement
Dificultad 2/5 1-3 horas Aptitud para principiantes 76/100
Los mantenedores suelen responder en 1 día
-
Dificultad 2/5 1-3 horas Aptitud para principiantes 68/100
Los mantenedores suelen responder en 1 día
-
Dificultad 4/5 3-5 días Aptitud para principiantes 56/100
Los mantenedores suelen responder en 1 día
-
Chapter show pages allocate ~21k+ objects per render for large chapters (18% of app allocations)Abiertoperformance
Dificultad 4/5 3-5 días Aptitud para principiantes 55/100
codebar/planner#2952 · 1 asignado ·
Los mantenedores suelen responder en 1 día
-
Workshop show pages allocate ~7.3k objects per request with no caching (28% of app allocations)Abiertoperformance
Dificultad 4/5 3-5 días Aptitud para principiantes 52/100
Los mantenedores suelen responder en 1 día
Todos los issues de codebar/planner
Issues similares
-
security
Dificultad 2/5 1-3 horas Aptitud para principiantes 68/100
Los mantenedores suelen responder en 1 día
-
OSCON 2016Abiertocontent
Dificultad 2/5 1-3 horas Aptitud para principiantes 68/100
rubyevents/rubyevents#2148 ·
Los mantenedores suelen responder en 1 día
-
Dificultad 2/5 1-3 horas Aptitud para principiantes 78/100
we-promise/sure#3838 · 2 comentarios ·
Los mantenedores suelen responder en 1 día
-
Allow simp/useradd 4.xAbierto
Dificultad 1/5 Menos de una hora Aptitud para principiantes 88/100
simp/pupmod-simp-pam#244 ·
Los mantenedores suelen responder en 7 días
-
Mend: dependency security vulnerability
Dificultad 2/5 1-3 horas Aptitud para principiantes 68/100
ManageIQ/manageiq-ui-classic#10341 ·
Los mantenedores suelen responder en 1 día