Skip to content

[dev] [Marfuen] mariano/fix-policy-publish-notifications#2590

Closed
github-actions[bot] wants to merge 18 commits intomainfrom
mariano/fix-policy-publish-notifications
Closed

[dev] [Marfuen] mariano/fix-policy-publish-notifications#2590
github-actions[bot] wants to merge 18 commits intomainfrom
mariano/fix-policy-publish-notifications

Conversation

@github-actions
Copy link
Copy Markdown
Contributor

@github-actions github-actions bot commented Apr 17, 2026

This is an automated pull request to merge mariano/fix-policy-publish-notifications into dev.
It was created by the [Auto Pull Request] action.


Summary by cubic

Fixes policy publish notifications and adds a daily policy acknowledgment digest so eligible members get clear, batched reminders. Publishing now resets acknowledgments only on a true publish transition.

  • New Features

    • Daily policyAcknowledgmentDigest task via @trigger.dev/sdk (14:00 UTC). Sends each compliance‑obligated member a digest of pending policies, batches to 25, respects org scoping, and handles multi‑org users.
    • Batched unsubscribe checks with getUnsubscribedEmails, reducing DB load and skipping opted‑out users.
    • New PolicyAcknowledgmentDigestEmail in @trycompai/email listing pending policies with portal links.
  • Bug Fixes

    • Clear signedBy and set lastPublishedAt only when status transitions to published (not on no‑op updates).
    • publishAll now clears signedBy for each policy and uses filterComplianceMembers to target the right recipients.

Written for commit e60ed5c. Summary will update on new commits.

Marfuen and others added 18 commits April 17, 2026 12:35
Adds signedBy: [] to the bulk-publish update so all four publish paths
behave consistently. Removes the vestigial members fetch and return field.
Adds a Jest spec covering both the clearing behaviour and the empty-drafts
early-return path.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Pure function that filters an org's policies to those a member has not
signed yet, respecting ALL vs DEPARTMENT visibility rules. Includes
6-case vitest suite mirroring the task-schedule-helpers pattern.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Adds PolicyAcknowledgmentDigestEmail template that renders a bulleted list of
pending policies with individual links and a single portal CTA, for use by the
daily acknowledgment digest scheduled task.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Scheduled Trigger.dev task that runs daily at 14:00 UTC, queries orgs with
active signing-required policies, and sends each compliance-obligated member
a digest email listing their pending policy acknowledgments.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…cribe, multi-org)

- Clear signedBy[] in updateById when status transitions to published
- Respect isUserUnsubscribed before sending digest emails
- Add updateById spec tests (publish clears signedBy, non-publish does not)
- Add digest test cases for unsubscribe skip and multi-org sending

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…signedBy clear on transition

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…ents

Replace the broken exact-match role filter in publishAll with filterComplianceMembers, which correctly handles comma-separated multi-role strings and resolves both built-in and custom role obligations.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…lure

The Trigger.dev deploy pipeline cannot resolve @trycompai/auth because
its dist is not built during the CI deploy step. Remove the transitive
dependency by inlining the compliance-obligation filter directly in the
helpers file, keeping identical behaviour.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
@vercel
Copy link
Copy Markdown

vercel bot commented Apr 17, 2026

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
app Ready Ready Preview, Comment Apr 17, 2026 8:01pm
comp-framework-editor Ready Ready Preview, Comment Apr 17, 2026 8:01pm
portal Ready Ready Preview, Comment Apr 17, 2026 8:01pm

Request Review

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.

2 issues found across 10 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="packages/email/lib/check-unsubscribe.ts">

<violation number="1" location="packages/email/lib/check-unsubscribe.ts:133">
P2: Skip member/role-setting queries when the preference type has no role-level mapping to avoid unnecessary DB work.</violation>
</file>

<file name="apps/app/src/trigger/tasks/task/policy-acknowledgment-digest-helpers.ts">

<violation number="1" location="apps/app/src/trigger/tasks/task/policy-acknowledgment-digest-helpers.ts:60">
P2: Handle invalid custom-role obligations JSON before parsing; the current unguarded `JSON.parse` can crash the digest task.</violation>
</file>

Reply with feedback, questions, or to request a fix. Tag @cubic-dev-ai to re-run a review, or fix all with cubic.

const survivingEmails = survivingUsers.map((u) => u.email);

// Step 2: look up org roles for all surviving users in one query
const memberRecords = await db.member.findMany({
Copy link
Copy Markdown

@cubic-dev-ai cubic-dev-ai bot Apr 17, 2026

Choose a reason for hiding this comment

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

P2: Skip member/role-setting queries when the preference type has no role-level mapping to avoid unnecessary DB work.

Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At packages/email/lib/check-unsubscribe.ts, line 133:

<comment>Skip member/role-setting queries when the preference type has no role-level mapping to avoid unnecessary DB work.</comment>

<file context>
@@ -51,6 +51,166 @@ interface RoleNotificationRecord {
+    const survivingEmails = survivingUsers.map((u) => u.email);
+
+    // Step 2: look up org roles for all surviving users in one query
+    const memberRecords = await db.member.findMany({
+      where: {
+        organizationId,
</file context>
Fix with Cubic

});
customObligationMap = Object.fromEntries(
customRoles.map((r) => {
const obligations =
Copy link
Copy Markdown

@cubic-dev-ai cubic-dev-ai bot Apr 17, 2026

Choose a reason for hiding this comment

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

P2: Handle invalid custom-role obligations JSON before parsing; the current unguarded JSON.parse can crash the digest task.

Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At apps/app/src/trigger/tasks/task/policy-acknowledgment-digest-helpers.ts, line 60:

<comment>Handle invalid custom-role obligations JSON before parsing; the current unguarded `JSON.parse` can crash the digest task.</comment>

<file context>
@@ -0,0 +1,109 @@
+    });
+    customObligationMap = Object.fromEntries(
+      customRoles.map((r) => {
+        const obligations =
+          typeof r.obligations === 'string'
+            ? JSON.parse(r.obligations)
</file context>
Fix with Cubic

@Marfuen Marfuen closed this Apr 17, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant