Skip to content

Implement follow/notifications for ballot questions#27

Merged
tripledoublev merged 2 commits intofeat/ballot-questionsfrom
feat/bq-follow
Apr 2, 2026
Merged

Implement follow/notifications for ballot questions#27
tripledoublev merged 2 commits intofeat/ballot-questionsfrom
feat/bq-follow

Conversation

@fastfadingviolets
Copy link
Copy Markdown

Summary

Add a short summary of the changes, and a reference to the original issue using # and the issue number, like #1

Checklist

  • On the frontend, I've made my strings translate-able.
  • If I've added shared components, I've added a storybook story.
  • I've made pages responsive and look good on mobile.
  • If I've added new Firestore queries, I've added any new required indexes to firestore.indexes.json (Please do not only create indexes through the Firebase Web UI, even though the error messages may reccommend it - indexes created this way may be obliterated by subsequent deploys)

Screenshots

Add some screenshots highlighting your changes.

Known issues

If you've run against limitations or caveats, include them here. Include follow-up issues as well.

Steps to test/reproduce

For each feature or bug fix, create a step by step list for how a reviewer can test it out. E.g.:

  1. Go to the home page
  2. Click on a testimony
  3. See that it's loaded with a loading spinner

@fastfadingviolets fastfadingviolets force-pushed the feat/bq-follow branch 2 times, most recently from 6ffea98 to 5c9425c Compare April 1, 2026 20:55
@fastfadingviolets fastfadingviolets marked this pull request as draft April 2, 2026 14:45
@fastfadingviolets fastfadingviolets marked this pull request as ready for review April 2, 2026 17:58
Comment on lines +33 to +40
const bqId: string | null = newData?.ballotQuestionId ?? null
let bqCourt: number | null = null
if (bqId) {
const bqSnap = await db.doc(`/ballotQuestions/${bqId}`).get()
bqCourt = bqSnap.exists
? (bqSnap.data()?.court as number) ?? null
: null
}
Copy link
Copy Markdown
Member

@tripledoublev tripledoublev Apr 2, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Non-blocking (future work): As this adds an extra ballotQuestions read for every testimony tied to a ballot question in order to recover court and since publish-time validation already loads the ballot question, it may be worth denormalizing ballotQuestionCourt on the published testimony (or event payload) in follow-up work to keep this trigger simpler.

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

yeah let me actually knock this out as part of this. we can just denormalize into the event payload.

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

it's already denormalized lol! i just had to grab it from the object. good catch.

}
}

if (notification.isBallotQuestionMatch && notification.ballotQuestionId) {
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Question for you: if a user follows both the bill and the ballot question, would the same testimony be in both digest sections? Or am I reading this wrong?

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No, bc they're different notification objects ultimately. If a user follows both they'd see notifications for the bill when the bill changes, for the ballot question when the ballot question changes. The source of truth for this is the userNotificationFeed, and that gets written to once when the testimony goes in, and points to either the ballot question if it's ballot question testimony, the bill if it's bill testimony

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ok, thanks for the clarification

} else {
ballotQuestionsById[bqId] = {
ballotQuestionId: bqId,
description: notification.header,
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

description: notification.header -> Does this mean this section is displaying the related bill title?

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This should come from the ballot question's description, which actually, I think is null right now.

@tripledoublev tripledoublev merged commit 0f6d743 into feat/ballot-questions Apr 2, 2026
8 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.

2 participants