Skip to content

Make delivery summary posting optional per program#498

Open
neal-bpm wants to merge 5 commits into
mainfrom
vn/slack-delivery-summary-optional
Open

Make delivery summary posting optional per program#498
neal-bpm wants to merge 5 commits into
mainfrom
vn/slack-delivery-summary-optional

Conversation

@neal-bpm
Copy link
Copy Markdown
Contributor

@neal-bpm neal-bpm commented May 12, 2026

Summary

Make delivery summary posting optional per program, allowing programs to control whether campaign
delivery summaries are posted to their configured Slack channel.

Problem

Previously, campaign delivery summaries were automatically posted to Slack whenever a program had a Slack channel configured. This didn't account for programs that may not want this automated notification,
creating unnecessary Slack traffic for some teams.

Solution

  • Added send_delivery_summaries boolean field to programs (defaults to false)
  • Made the checkbox visible in the form only when a Slack channel is selected, preventing misconfiguration
  • Updated CampaignSummaryPoster to check this flag before posting summaries

Changes

Backend:

  • Added migration to add send_delivery_summaries column to programs table
  • Updated Program schema to include the new field
  • Modified CampaignSummaryPoster.post_summary_for_campaign/1 to check the flag before posting
  • Changed logging from warning to info when summaries are skipped due to the flag

Frontend:

  • Added conditional checkbox in program form that only displays when a Slack channel is selected
  • Uses :if directive to prevent showing the option when channel is not configured

Note

Programs that want delivery summaries need to explicitly enable the checkbox.

Checklist before requesting a review

  • I have performed a self-review of my code
  • [] If it is a core feature, I have added tests.
  • Are there other PRs or Issues that I should link to here?
  • Will this be part of a product update? If yes, please write one phrase
    about this update in the description above.
    Opt-in delivery summaries: programs control whether campaign delivery summaries are posted to Slack channel.

Summary by cubic

Make Slack delivery summaries opt-in per program so teams control whether summaries are posted. Default is off; existing programs with a Slack channel stay enabled, with stricter checks for safety.

  • New Features

    • Added send_delivery_summaries on programs (default false).
    • Show the checkbox only when a Slack channel is set in the Program form.
    • CampaignSummaryPoster respects the flag; skips and logs info when disabled or no channel (no Slack error notification when channel is missing).
    • Stricter check: only posts when the flag is explicitly true (treats all other values as disabled).
  • Migration

    • Run the new migrations.
    • Auto-enables send_delivery_summaries for programs that already have a Slack channel.
    • Adds a NOT NULL constraint to send_delivery_summaries for data integrity.

Written for commit 461da10. Summary will update on new commits. Review in cubic

Summary by CodeRabbit

  • New Features

    • Added a configurable setting to control whether campaign delivery summaries are sent to Slack.
    • Programs can toggle delivery summary notifications via a new checkbox in settings (visible only when a Slack channel is configured).
    • Campaign summaries are only posted when a program has a Slack channel configured and the setting is enabled.
  • Chores

    • Added database column (default false), enabled the setting for existing programs with Slack channels, and enforced a non-null constraint.

Review Change Stack

  program

Programs may have different preferences about whether campaign delivery summaries should be posted to their Slack channel
- Added `send_delivery_summaries`   boolean field to programs (defaults
  false)
  - Conditionally render the checkbox in the form only when a Slack channel is selected, preventing accidental configuration without a channel
  - Updated CampaignSummaryPoster to  check this flag before posting
@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented May 12, 2026

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: 6a780ad7-0576-4cfd-85a6-236078556bd4

📥 Commits

Reviewing files that changed from the base of the PR and between b45ceaf and 461da10.

📒 Files selected for processing (1)
  • priv/repo/migrations/20260526000001_add_not_null_constraint_to_send_delivery_summaries.exs
✅ Files skipped from review due to trivial changes (1)
  • priv/repo/migrations/20260526000001_add_not_null_constraint_to_send_delivery_summaries.exs

📝 Walkthrough

Walkthrough

Adds a per-program boolean send_delivery_summaries (schema + migrations + changeset). The program form shows a conditional checkbox when a Slack channel exists. Campaign summary posting is gated: it logs and exits if the flag is disabled or no channel is set; otherwise it proceeds to post.

Changes

Delivery Summaries Feature Flag

Layer / File(s) Summary
Schema field and database migrations
lib/bike_brigade/delivery/program.ex, priv/repo/migrations/20260512195708_add_send_delivery_summaries_to_programs.exs, priv/repo/migrations/20260519000001_enable_send_delivery_summaries_for_programs_with_slack_channel.exs, priv/repo/migrations/20260526000001_add_not_null_constraint_to_send_delivery_summaries.exs
Adds send_delivery_summaries boolean field (default false) to Program schema, permits it in the changeset, creates the column, backfills true for programs with slack_channel_id, and makes the column non-nullable.
Program form checkbox control
lib/bike_brigade_web/live/program_live/form_component.html.heex
Adds a checkbox send_delivery_summaries that is rendered only when slack_channel_id is present.
Campaign summary posting gate
lib/bike_brigade/campaign_summary_poster.ex
post_summary_for_campaign/1 now supplies the program's slack_channel_id and send_delivery_summaries to do_post_summary/3; new guarded clauses log-and-skip when disabled or when no channel is configured, otherwise the existing posting pipeline runs.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

Possibly related PRs

  • bikebrigade/dispatch#486: Modifies campaign summary posting flow in the same module; both touch post_summary_for_campaign/1 behavior.

Suggested reviewers

  • mveytsman

Poem

🐰 A tiny flag hops into the light,
Forms now whisper “post” only when right,
Migrations plant seeds, the schema grows,
Slack hears summaries when the checkbox glows,
Hooray — deliveries rest easy tonight!

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 40.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Title check ✅ Passed The title 'Make delivery summary posting optional per program' accurately summarizes the main change: adding opt-in control for Slack delivery summaries at the program level.
Description check ✅ Passed The description covers the problem, solution, and changes comprehensively, addressing all template requirements with detailed backend and frontend modifications plus a product update note.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch vn/slack-delivery-summary-optional

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

  channel configured. This is the existing behaviour.
@neal-bpm neal-bpm requested a review from mveytsman May 19, 2026 19:40
@neal-bpm neal-bpm marked this pull request as ready for review May 19, 2026 19:40
Copy link
Copy Markdown

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 3

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@lib/bike_brigade/campaign_summary_poster.ex`:
- Around line 69-77: Add a defensive clause to do_post_summary/3 so non-true
values for the send_delivery_summaries flag (nil, false, or any other unexpected
value) don't cause a FunctionClauseError; for example add a clause like defp
do_post_summary(campaign, _channel_id, flag) when flag != true do
Logger.info("Skipping campaign #{campaign.id}: delivery summaries not enabled
for program (flag: #{inspect(flag)})") end to catch nil/false/invalid flag
values before the do_post_summary(campaign, channel_id, true) clause.

In
`@priv/repo/migrations/20260512195708_add_send_delivery_summaries_to_programs.exs`:
- Line 6: The migration currently adds the column send_delivery_summaries with a
default but allows NULLs; update the migration's change function so the add
statement for :send_delivery_summaries uses null: false (e.g. add
:send_delivery_summaries, :boolean, default: false, null: false) to enforce a
non-null boolean at the DB level; ensure the migration's down/rollback behavior
(or change callback) remains correct after this change.

In
`@priv/repo/migrations/20260519000001_enable_send_delivery_summaries_for_programs_with_slack_channel.exs`:
- Around line 8-12: The migration currently references the schema module
BikeBrigade.Delivery.Program which can break replay; change the query to use the
table name string instead (e.g., from(p in "programs", update: [set:
[send_delivery_summaries: true]], where: not is_nil(p.slack_channel_id))) and
keep the Repo.update_all call, so the migration uses raw table-based Ecto
queries rather than the application schema module.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: 0231233d-f6ef-4f85-bbc2-b8c75047e0ec

📥 Commits

Reviewing files that changed from the base of the PR and between ff808be and 1ecd4fd.

📒 Files selected for processing (5)
  • lib/bike_brigade/campaign_summary_poster.ex
  • lib/bike_brigade/delivery/program.ex
  • lib/bike_brigade_web/live/program_live/form_component.html.heex
  • priv/repo/migrations/20260512195708_add_send_delivery_summaries_to_programs.exs
  • priv/repo/migrations/20260519000001_enable_send_delivery_summaries_for_programs_with_slack_channel.exs

Comment thread lib/bike_brigade/campaign_summary_poster.ex Outdated
Copy link
Copy Markdown

@cubic-dev-ai cubic-dev-ai Bot left a comment

Choose a reason for hiding this comment

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

3 issues found across 5 files

Prompt for AI agents (unresolved issues)

Check if these issues are valid — if so, understand the root cause of each and fix them. If appropriate, use sub-agents to investigate and fix each issue separately.


<file name="priv/repo/migrations/20260519000001_enable_send_delivery_summaries_for_programs_with_slack_channel.exs">

<violation number="1" location="priv/repo/migrations/20260519000001_enable_send_delivery_summaries_for_programs_with_slack_channel.exs:8">
P2: Using application schema modules (`BikeBrigade.Delivery.Program`) in migrations can break replay on new environments if the schema later changes. Use raw SQL via `execute/1` instead to keep the migration self-contained.</violation>
</file>

Reply with feedback, questions, or to request a fix.

Re-trigger cubic

Comment thread lib/bike_brigade/campaign_summary_poster.ex Outdated
alias BikeBrigade.Repo

def up do
from(prog in BikeBrigade.Delivery.Program,
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P2: Using application schema modules (BikeBrigade.Delivery.Program) in migrations can break replay on new environments if the schema later changes. Use raw SQL via execute/1 instead to keep the migration self-contained.

Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At priv/repo/migrations/20260519000001_enable_send_delivery_summaries_for_programs_with_slack_channel.exs, line 8:

<comment>Using application schema modules (`BikeBrigade.Delivery.Program`) in migrations can break replay on new environments if the schema later changes. Use raw SQL via `execute/1` instead to keep the migration self-contained.</comment>

<file context>
@@ -0,0 +1,16 @@
+  alias BikeBrigade.Repo
+
+  def up do
+    from(prog in BikeBrigade.Delivery.Program,
+      update: [set: [send_delivery_summaries: true]],
+      where: not is_nil(prog.slack_channel_id)
</file context>

Copy link
Copy Markdown
Member

@mveytsman mveytsman left a comment

Choose a reason for hiding this comment

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

the column should be nil: false, you'll need a third miogration to set null false, this addresses the code rabbit errors

neal-bpm and others added 3 commits May 26, 2026 14:25
Co-authored-by: cubic-dev-ai[bot] <191113872+cubic-dev-ai[bot]@users.noreply.github.com>
  - Use guard clause in pattern matching to handle all falsy values
  - Add NOT NULL constraint to send_delivery_summaries column for data integrity
@neal-bpm neal-bpm requested a review from mveytsman May 26, 2026 20:06
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

Status: No status

Development

Successfully merging this pull request may close these issues.

2 participants