Skip to content

feat(webapp): Platform notifications admin imporovements#3324

Merged
0ski merged 1 commit intomainfrom
oskar/feat-platform-notifications-admin
Apr 13, 2026
Merged

feat(webapp): Platform notifications admin imporovements#3324
0ski merged 1 commit intomainfrom
oskar/feat-platform-notifications-admin

Conversation

@0ski
Copy link
Copy Markdown
Collaborator

@0ski 0ski commented Apr 3, 2026

  • bugfix to show the changelog to the target audience
  • more functionality for admins, to edit, delete and archive notifications

@changeset-bot
Copy link
Copy Markdown

changeset-bot bot commented Apr 3, 2026

⚠️ No Changeset found

Latest commit: e83679c

Merging this PR will not cause a version bump for any packages. If these changes should not result in a new version, you're good to go. If these changes should result in a version bump, you need to add a changeset.

This PR includes no changesets

When changesets are added to this PR, you'll see the packages that this PR includes changesets for and the associated semver types

Click here to learn what changesets are, and how to add one.

Click here if you're a maintainer who wants to add a changeset to this PR

@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai bot commented Apr 3, 2026

Walkthrough

This pull request adds organization and project context scoping to help/feedback and changelog features, and significantly refactors the admin notifications system. The component props for HelpAndFeedback and related components are extended to accept optional organizationId and projectId parameters, which are propagated through the component hierarchy and passed to the useRecentChangelogs hook for context-aware changelog filtering. The admin notifications route and service layer are restructured to support CRUD operations (delete, publish-now, edit), introduce a dialog-based form UI replacing the inline create form, add scope-based filtering (GLOBAL|USER|ORGANIZATION|PROJECT), implement a new releasing notification status for imminent notifications, and replace hideArchived filtering with hideInactive. The service layer gains a verifyOrgMembership utility, updates the getRecentChangelogs signature to accept userId and optional context parameters, and adds functions for notification update, delete, publish, and archive operations.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~40 minutes

🚥 Pre-merge checks | ✅ 1 | ❌ 2

❌ Failed checks (2 warnings)

Check name Status Explanation Resolution
Description check ⚠️ Warning The PR description is minimal and does not follow the provided template structure, missing required sections like checklist, testing details, and changelog details. Follow the template by adding all required sections including a checklist, detailed testing steps, and a comprehensive changelog entry to properly document the changes.
Docstring Coverage ⚠️ Warning Docstring coverage is 11.90% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (1 passed)
Check name Status Explanation
Title check ✅ Passed The title 'feat(webapp): Platform notifications admin imporovements' is related to the main changes but contains a typo ('imporovements' instead of 'improvements') and is somewhat broad, though it accurately captures the core feature being added.

✏️ 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 oskar/feat-platform-notifications-admin

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.

coderabbitai[bot]

This comment was marked as resolved.

deepshekhardas pushed a commit to deepshekhardas/trigger.dev that referenced this pull request Apr 7, 2026
@0ski 0ski marked this pull request as ready for review April 13, 2026 08:36
@0ski 0ski force-pushed the oskar/feat-platform-notifications-admin branch from 360060a to e83679c Compare April 13, 2026 08:36
Copy link
Copy Markdown
Contributor

@devin-ai-integration devin-ai-integration bot left a comment

Choose a reason for hiding this comment

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

✅ Devin Review: No Issues Found

Devin Review analyzed this PR and found no potential bugs to report.

View in Devin Review to see 5 additional findings.

Open in Devin Review

Copy link
Copy Markdown
Contributor

@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.

🧹 Nitpick comments (2)
apps/webapp/app/services/platformNotifications.server.ts (2)

292-319: Consider distinguishing "no membership" from "membership but invalid project".

The function silently returns {} when membership verification fails, making it impossible for callers to distinguish between "user provided no organizationId" vs "user is not a member of the organization". This could mask authorization failures.

If explicit failure signaling is not needed for the current use case, consider at least adding a brief comment explaining that silent fallback is intentional.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@apps/webapp/app/services/platformNotifications.server.ts` around lines 292 -
319, The verifyOrgMembership function currently returns {} for multiple
different failure cases which hides whether the caller omitted organizationId,
the user is not a member, or the project is invalid; update verifyOrgMembership
to return an explicit discriminated result (e.g., { status: 'ok',
organizationId, projectId } | { status: 'no_org_id' } | { status: 'not_member' }
| { status: 'invalid_project' }) or throw specific errors so callers can
distinguish cases; change the function signature and replace the three
blank-object returns with the appropriate discriminated responses (refer to
verifyOrgMembership, prisma.orgMember and prisma.project usage) and update call
sites to handle the new statuses, or if you intend the current silent behavior,
add a clear comment above verifyOrgMembership explaining the intentional
fallback.

781-797: Inconsistent error handling in mutation functions.

deletePlatformNotification, publishNowPlatformNotification, and archivePlatformNotification will throw Prisma errors if the record doesn't exist, but the handlers (handleArchiveAction, handleDeleteAction, handlePublishNowAction) don't wrap these calls in try-catch. This is inconsistent with createPlatformNotification and updatePlatformNotification, which use the neverthrow Result type and are properly handled with error checks. Consider wrapping the three mutation functions with error handling to match the established pattern.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@apps/webapp/app/services/platformNotifications.server.ts` around lines 781 -
797, Change the three mutation helpers (deletePlatformNotification,
publishNowPlatformNotification, archivePlatformNotification) to mirror the
create/update pattern by returning a neverthrow Result instead of letting Prisma
throw: wrap the Prisma call in try-catch, return ok(void 0) on success and
err(error) on failure (import Result/ok/err from neverthrow), and update call
sites/handlers if needed to handle the Result; this ensures consistency with
createPlatformNotification and updatePlatformNotification and prevents unhandled
Prisma exceptions.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Nitpick comments:
In `@apps/webapp/app/services/platformNotifications.server.ts`:
- Around line 292-319: The verifyOrgMembership function currently returns {} for
multiple different failure cases which hides whether the caller omitted
organizationId, the user is not a member, or the project is invalid; update
verifyOrgMembership to return an explicit discriminated result (e.g., { status:
'ok', organizationId, projectId } | { status: 'no_org_id' } | { status:
'not_member' } | { status: 'invalid_project' }) or throw specific errors so
callers can distinguish cases; change the function signature and replace the
three blank-object returns with the appropriate discriminated responses (refer
to verifyOrgMembership, prisma.orgMember and prisma.project usage) and update
call sites to handle the new statuses, or if you intend the current silent
behavior, add a clear comment above verifyOrgMembership explaining the
intentional fallback.
- Around line 781-797: Change the three mutation helpers
(deletePlatformNotification, publishNowPlatformNotification,
archivePlatformNotification) to mirror the create/update pattern by returning a
neverthrow Result instead of letting Prisma throw: wrap the Prisma call in
try-catch, return ok(void 0) on success and err(error) on failure (import
Result/ok/err from neverthrow), and update call sites/handlers if needed to
handle the Result; this ensures consistency with createPlatformNotification and
updatePlatformNotification and prevents unhandled Prisma exceptions.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro

Run ID: 79d98d09-4f20-4ba3-8efd-58e1be185ba1

📥 Commits

Reviewing files that changed from the base of the PR and between 360060a and e83679c.

📒 Files selected for processing (7)
  • apps/webapp/app/components/navigation/HelpAndFeedbackPopover.tsx
  • apps/webapp/app/components/navigation/OrganizationSettingsSideMenu.tsx
  • apps/webapp/app/components/navigation/SideMenu.tsx
  • apps/webapp/app/routes/admin.notifications.tsx
  • apps/webapp/app/routes/resources.platform-changelogs.tsx
  • apps/webapp/app/routes/resources.platform-notifications.tsx
  • apps/webapp/app/services/platformNotifications.server.ts
✅ Files skipped from review due to trivial changes (2)
  • apps/webapp/app/routes/resources.platform-notifications.tsx
  • apps/webapp/app/routes/admin.notifications.tsx
🚧 Files skipped from review as they are similar to previous changes (1)
  • apps/webapp/app/routes/resources.platform-changelogs.tsx
📜 Review details
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (27)
  • GitHub Check: units / webapp / 🧪 Unit Tests: Webapp (3, 8)
  • GitHub Check: units / webapp / 🧪 Unit Tests: Webapp (4, 8)
  • GitHub Check: units / webapp / 🧪 Unit Tests: Webapp (8, 8)
  • GitHub Check: units / internal / 🧪 Unit Tests: Internal (7, 8)
  • GitHub Check: units / webapp / 🧪 Unit Tests: Webapp (7, 8)
  • GitHub Check: units / internal / 🧪 Unit Tests: Internal (8, 8)
  • GitHub Check: units / webapp / 🧪 Unit Tests: Webapp (1, 8)
  • GitHub Check: units / webapp / 🧪 Unit Tests: Webapp (2, 8)
  • GitHub Check: units / webapp / 🧪 Unit Tests: Webapp (5, 8)
  • GitHub Check: units / webapp / 🧪 Unit Tests: Webapp (6, 8)
  • GitHub Check: units / internal / 🧪 Unit Tests: Internal (5, 8)
  • GitHub Check: units / internal / 🧪 Unit Tests: Internal (1, 8)
  • GitHub Check: units / internal / 🧪 Unit Tests: Internal (6, 8)
  • GitHub Check: units / internal / 🧪 Unit Tests: Internal (3, 8)
  • GitHub Check: units / internal / 🧪 Unit Tests: Internal (2, 8)
  • GitHub Check: units / internal / 🧪 Unit Tests: Internal (4, 8)
  • GitHub Check: units / packages / 🧪 Unit Tests: Packages (1, 1)
  • GitHub Check: e2e / 🧪 CLI v3 tests (ubuntu-latest - pnpm)
  • GitHub Check: e2e / 🧪 CLI v3 tests (ubuntu-latest - npm)
  • GitHub Check: e2e / 🧪 CLI v3 tests (windows-latest - pnpm)
  • GitHub Check: sdk-compat / Node.js 22.12 (ubuntu-latest)
  • GitHub Check: sdk-compat / Node.js 20.20 (ubuntu-latest)
  • GitHub Check: e2e / 🧪 CLI v3 tests (windows-latest - npm)
  • GitHub Check: sdk-compat / Bun Runtime
  • GitHub Check: sdk-compat / Deno Runtime
  • GitHub Check: sdk-compat / Cloudflare Workers
  • GitHub Check: typecheck / typecheck
🧰 Additional context used
📓 Path-based instructions (12)
**/*.{ts,tsx}

📄 CodeRabbit inference engine (.github/copilot-instructions.md)

**/*.{ts,tsx}: Use types over interfaces for TypeScript
Avoid using enums; prefer string unions or const objects instead

Files:

  • apps/webapp/app/components/navigation/OrganizationSettingsSideMenu.tsx
  • apps/webapp/app/components/navigation/HelpAndFeedbackPopover.tsx
  • apps/webapp/app/components/navigation/SideMenu.tsx
  • apps/webapp/app/services/platformNotifications.server.ts
{packages/core,apps/webapp}/**/*.{ts,tsx}

📄 CodeRabbit inference engine (.github/copilot-instructions.md)

Use zod for validation in packages/core and apps/webapp

Files:

  • apps/webapp/app/components/navigation/OrganizationSettingsSideMenu.tsx
  • apps/webapp/app/components/navigation/HelpAndFeedbackPopover.tsx
  • apps/webapp/app/components/navigation/SideMenu.tsx
  • apps/webapp/app/services/platformNotifications.server.ts
**/*.{ts,tsx,js,jsx}

📄 CodeRabbit inference engine (.github/copilot-instructions.md)

Use function declarations instead of default exports

Files:

  • apps/webapp/app/components/navigation/OrganizationSettingsSideMenu.tsx
  • apps/webapp/app/components/navigation/HelpAndFeedbackPopover.tsx
  • apps/webapp/app/components/navigation/SideMenu.tsx
  • apps/webapp/app/services/platformNotifications.server.ts
apps/webapp/app/**/*.{ts,tsx}

📄 CodeRabbit inference engine (.cursor/rules/webapp.mdc)

Access all environment variables through the env export of env.server.ts instead of directly accessing process.env in the Trigger.dev webapp

Files:

  • apps/webapp/app/components/navigation/OrganizationSettingsSideMenu.tsx
  • apps/webapp/app/components/navigation/HelpAndFeedbackPopover.tsx
  • apps/webapp/app/components/navigation/SideMenu.tsx
  • apps/webapp/app/services/platformNotifications.server.ts
apps/webapp/**/*.{ts,tsx}

📄 CodeRabbit inference engine (.cursor/rules/webapp.mdc)

apps/webapp/**/*.{ts,tsx}: When importing from @trigger.dev/core in the webapp, use subpath exports from the package.json instead of importing from the root path
Follow the Remix 2.1.0 and Express server conventions when updating the main trigger.dev webapp

Files:

  • apps/webapp/app/components/navigation/OrganizationSettingsSideMenu.tsx
  • apps/webapp/app/components/navigation/HelpAndFeedbackPopover.tsx
  • apps/webapp/app/components/navigation/SideMenu.tsx
  • apps/webapp/app/services/platformNotifications.server.ts
**/*.{js,ts,jsx,tsx,json,md,yaml,yml}

📄 CodeRabbit inference engine (AGENTS.md)

Format code using Prettier before committing

Files:

  • apps/webapp/app/components/navigation/OrganizationSettingsSideMenu.tsx
  • apps/webapp/app/components/navigation/HelpAndFeedbackPopover.tsx
  • apps/webapp/app/components/navigation/SideMenu.tsx
  • apps/webapp/app/services/platformNotifications.server.ts
apps/**/*

📄 CodeRabbit inference engine (CLAUDE.md)

When modifying only server components (apps/webapp/, apps/supervisor/, etc.) with no package changes, add a .server-changes/ file instead of a changeset

Files:

  • apps/webapp/app/components/navigation/OrganizationSettingsSideMenu.tsx
  • apps/webapp/app/components/navigation/HelpAndFeedbackPopover.tsx
  • apps/webapp/app/components/navigation/SideMenu.tsx
  • apps/webapp/app/services/platformNotifications.server.ts
apps/webapp/**/*.{tsx,jsx}

📄 CodeRabbit inference engine (apps/webapp/CLAUDE.md)

Only use useCallback/useMemo for context provider values, expensive derived data with external dependencies, or stable refs required by dependency arrays; don't wrap ordinary event handlers or trivial computations

Files:

  • apps/webapp/app/components/navigation/OrganizationSettingsSideMenu.tsx
  • apps/webapp/app/components/navigation/HelpAndFeedbackPopover.tsx
  • apps/webapp/app/components/navigation/SideMenu.tsx
apps/webapp/**/*.{ts,tsx,js,jsx}

📄 CodeRabbit inference engine (apps/webapp/CLAUDE.md)

Use named constants for sentinel/placeholder values instead of raw string literals scattered across comparisons

Files:

  • apps/webapp/app/components/navigation/OrganizationSettingsSideMenu.tsx
  • apps/webapp/app/components/navigation/HelpAndFeedbackPopover.tsx
  • apps/webapp/app/components/navigation/SideMenu.tsx
  • apps/webapp/app/services/platformNotifications.server.ts
apps/webapp/app/services/**/*.server.{ts,tsx}

📄 CodeRabbit inference engine (.cursor/rules/webapp.mdc)

Separate testable services from configuration files; follow the pattern of realtimeClient.server.ts (testable service) and realtimeClientGlobal.server.ts (configuration) in the webapp

Files:

  • apps/webapp/app/services/platformNotifications.server.ts
**/*.ts

📄 CodeRabbit inference engine (.cursor/rules/otel-metrics.mdc)

**/*.ts: When creating or editing OTEL metrics (counters, histograms, gauges), ensure metric attributes have low cardinality by using only enums, booleans, bounded error codes, or bounded shard IDs
Do not use high-cardinality attributes in OTEL metrics such as UUIDs/IDs (envId, userId, runId, projectId, organizationId), unbounded integers (itemCount, batchSize, retryCount), timestamps (createdAt, startTime), or free-form strings (errorMessage, taskName, queueName)
When exporting OTEL metrics via OTLP to Prometheus, be aware that the exporter automatically adds unit suffixes to metric names (e.g., 'my_duration_ms' becomes 'my_duration_ms_milliseconds', 'my_counter' becomes 'my_counter_total'). Account for these transformations when writing Grafana dashboards or Prometheus queries

**/*.ts: Use typecheck to verify changes in apps and internal packages (apps/*, internal-packages/*), not build - building proves almost nothing about correctness
When writing Trigger.dev tasks, always import from @trigger.dev/sdk. Never use @trigger.dev/sdk/v3 or deprecated client.defineJob
Add crumbs as you write code - mark lines with // @Crumbs or wrap blocks in `// `#region` `@crumbs for agentcrumbs debug tracing, then strip before merge

Files:

  • apps/webapp/app/services/platformNotifications.server.ts
apps/webapp/**/*.server.{ts,tsx}

📄 CodeRabbit inference engine (apps/webapp/CLAUDE.md)

apps/webapp/**/*.server.{ts,tsx}: Environment variables must be accessed via the env export from app/env.server.ts and never use process.env directly
Always use findFirst instead of findUnique in Prisma queries due to implicit DataLoader batching issues and performance concerns

Files:

  • apps/webapp/app/services/platformNotifications.server.ts
🧠 Learnings (12)
📚 Learning: 2026-04-02T19:18:34.807Z
Learnt from: samejr
Repo: triggerdotdev/trigger.dev PR: 3319
File: apps/webapp/app/routes/_app.orgs.$organizationSlug.projects.$projectParam.env.$envParam.waitpoints.tokens/route.tsx:249-258
Timestamp: 2026-04-02T19:18:34.807Z
Learning: In `apps/webapp/app/routes/_app.orgs.$organizationSlug.projects.$projectParam.env.$envParam.waitpoints.tokens/route.tsx`, the `onCollapseChange={() => {}}` no-op on the `ResizablePanel` for the waitpoint inspector is intentional. The panel collapse is controlled externally via `collapsed={!isShowingWaitpoint}` (driven by URL params), so the callback is deliberately left as a no-op. Do not flag this as a missing implementation.

Applied to files:

  • apps/webapp/app/components/navigation/OrganizationSettingsSideMenu.tsx
  • apps/webapp/app/components/navigation/SideMenu.tsx
📚 Learning: 2026-04-03T11:54:21.609Z
Learnt from: samejr
Repo: triggerdotdev/trigger.dev PR: 3319
File: apps/webapp/app/routes/_app.orgs.$organizationSlug.projects.$projectParam.env.$envParam.regions/route.tsx:265-267
Timestamp: 2026-04-03T11:54:21.609Z
Learning: In `apps/webapp/app/routes/_app.orgs.$organizationSlug.projects.$projectParam.env.$envParam.regions/route.tsx`, the `TableCellMenu` for the "Set as default" region action intentionally uses `hiddenButtons` (hover-only visibility) rather than `visibleButtons`. This is a deliberate UX design choice by the team. Do not flag the hover-only visibility as an accessibility concern for this specific instance.

Applied to files:

  • apps/webapp/app/components/navigation/OrganizationSettingsSideMenu.tsx
📚 Learning: 2026-02-11T16:37:32.429Z
Learnt from: matt-aitken
Repo: triggerdotdev/trigger.dev PR: 3019
File: apps/webapp/app/components/primitives/charts/Card.tsx:26-30
Timestamp: 2026-02-11T16:37:32.429Z
Learning: In projects using react-grid-layout, avoid relying on drag-handle class to imply draggability. Ensure drag-handle elements only affect dragging when the parent grid item is configured draggable in the layout; conditionally apply cursor styles based on the draggable prop. This improves correctness and accessibility.

Applied to files:

  • apps/webapp/app/components/navigation/OrganizationSettingsSideMenu.tsx
  • apps/webapp/app/components/navigation/HelpAndFeedbackPopover.tsx
  • apps/webapp/app/components/navigation/SideMenu.tsx
📚 Learning: 2026-03-22T13:26:12.060Z
Learnt from: ericallam
Repo: triggerdotdev/trigger.dev PR: 3244
File: apps/webapp/app/components/code/TextEditor.tsx:81-86
Timestamp: 2026-03-22T13:26:12.060Z
Learning: In the triggerdotdev/trigger.dev codebase, do not flag `navigator.clipboard.writeText(...)` calls for `missing-await`/`unhandled-promise` issues. These clipboard writes are intentionally invoked without `await` and without `catch` handlers across the project; keep that behavior consistent when reviewing TypeScript/TSX files (e.g., usages like in `apps/webapp/app/components/code/TextEditor.tsx`).

Applied to files:

  • apps/webapp/app/components/navigation/OrganizationSettingsSideMenu.tsx
  • apps/webapp/app/components/navigation/HelpAndFeedbackPopover.tsx
  • apps/webapp/app/components/navigation/SideMenu.tsx
  • apps/webapp/app/services/platformNotifications.server.ts
📚 Learning: 2026-03-22T19:24:14.403Z
Learnt from: matt-aitken
Repo: triggerdotdev/trigger.dev PR: 3187
File: apps/webapp/app/v3/services/alerts/deliverErrorGroupAlert.server.ts:200-204
Timestamp: 2026-03-22T19:24:14.403Z
Learning: In the triggerdotdev/trigger.dev codebase, webhook URLs are not expected to contain embedded credentials/secrets (e.g., fields like `ProjectAlertWebhookProperties` should only hold credential-free webhook endpoints). During code review, if you see logging or inclusion of raw webhook URLs in error messages, do not automatically treat it as a credential-leak/secrets-in-logs issue by default—first verify the URL does not contain embedded credentials (for example, no username/password in the URL, no obvious secret/token query params or fragments). If the URL is credential-free per this project’s conventions, allow the logging.

Applied to files:

  • apps/webapp/app/components/navigation/OrganizationSettingsSideMenu.tsx
  • apps/webapp/app/components/navigation/HelpAndFeedbackPopover.tsx
  • apps/webapp/app/components/navigation/SideMenu.tsx
  • apps/webapp/app/services/platformNotifications.server.ts
📚 Learning: 2026-02-11T16:50:14.167Z
Learnt from: matt-aitken
Repo: triggerdotdev/trigger.dev PR: 3019
File: apps/webapp/app/routes/resources.orgs.$organizationSlug.projects.$projectParam.env.$envParam.dashboards.$dashboardId.widgets.tsx:126-131
Timestamp: 2026-02-11T16:50:14.167Z
Learning: In apps/webapp/app/routes/resources.orgs.$organizationSlug.projects.$projectParam.env.$envParam.dashboards.$dashboardId.widgets.tsx, MetricsDashboard entities are intentionally scoped to the organization level, not the project level. The dashboard lookup should filter by organizationId only (not projectId), allowing dashboards to be accessed across projects within the same organization. The optional projectId field on MetricsDashboard serves other purposes and should not be used as an authorization constraint.

Applied to files:

  • apps/webapp/app/components/navigation/HelpAndFeedbackPopover.tsx
📚 Learning: 2026-04-01T13:27:35.831Z
Learnt from: samejr
Repo: triggerdotdev/trigger.dev PR: 3308
File: apps/webapp/app/routes/_app.orgs.$organizationSlug.projects.$projectParam.env.$envParam.models._index/route.tsx:579-584
Timestamp: 2026-04-01T13:27:35.831Z
Learning: In `apps/webapp/app/routes/_app.orgs.$organizationSlug.projects.$projectParam.env.$envParam.models._index/route.tsx`, the `useEffect` inside `CompareDialog` intentionally uses `[open]` as its only dependency. This is a deliberate "fetch-on-open" pattern: the fetcher.load call should fire only when the dialog opens, not on every reference change of `models`, `organization`, `project`, or `environment`. Do not flag this as a missing-dependency lint issue.

Applied to files:

  • apps/webapp/app/components/navigation/HelpAndFeedbackPopover.tsx
📚 Learning: 2026-03-26T10:00:07.558Z
Learnt from: 0ski
Repo: triggerdotdev/trigger.dev PR: 3254
File: packages/cli-v3/src/apiClient.ts:61-86
Timestamp: 2026-03-26T10:00:07.558Z
Learning: In triggerdotdev/trigger.dev, the `api.v1.platform-notifications` loader filters `PlatformNotification` records by `surface: "CLI"` before returning them. As a result, `card` and `changelog` notification types (which are `WEBAPP`-only) never reach the CLI endpoint, and the `CliPlatformNotificationResponseSchema` in `packages/cli-v3/src/apiClient.ts` does not need to include those types in its `data.type` enum. Do not flag missing `card`/`changelog` enum values in this schema as a bug.

Applied to files:

  • apps/webapp/app/services/platformNotifications.server.ts
📚 Learning: 2026-03-26T10:02:25.354Z
Learnt from: 0ski
Repo: triggerdotdev/trigger.dev PR: 3254
File: apps/webapp/app/services/platformNotifications.server.ts:363-385
Timestamp: 2026-03-26T10:02:25.354Z
Learning: In `triggerdotdev/trigger.dev`, the `getNextCliNotification` fallback in `apps/webapp/app/services/platformNotifications.server.ts` intentionally uses `prisma.orgMember.findFirst` (single org) when no `projectRef` is provided. This is acceptable for v1 because the CLI (`dev` and `login` commands) always passes `projectRef` in normal usage, making the fallback a rare edge case. Do not flag the single-org fallback as a multi-org correctness bug in this file.

Applied to files:

  • apps/webapp/app/services/platformNotifications.server.ts
📚 Learning: 2026-03-02T12:43:37.906Z
Learnt from: CR
Repo: triggerdotdev/trigger.dev PR: 0
File: packages/core/CLAUDE.md:0-0
Timestamp: 2026-03-02T12:43:37.906Z
Learning: Exercise caution with changes to trigger.dev/core as they affect both the customer-facing SDK and server-side webapp - breaking changes can impact deployed user tasks and the platform simultaneously

Applied to files:

  • apps/webapp/app/services/platformNotifications.server.ts
📚 Learning: 2026-03-25T15:29:25.889Z
Learnt from: CR
Repo: triggerdotdev/trigger.dev PR: 0
File: .cursor/rules/writing-tasks.mdc:0-0
Timestamp: 2026-03-25T15:29:25.889Z
Learning: Applies to **/trigger/**/*.{ts,tsx,js,jsx} : Use `schemaTask()` from `trigger.dev/sdk` with a Zod schema for payload validation

Applied to files:

  • apps/webapp/app/services/platformNotifications.server.ts
📚 Learning: 2026-03-26T09:02:07.973Z
Learnt from: myftija
Repo: triggerdotdev/trigger.dev PR: 3274
File: apps/webapp/app/services/runsReplicationService.server.ts:922-924
Timestamp: 2026-03-26T09:02:07.973Z
Learning: When parsing Trigger.dev task run annotations in server-side services, keep `TaskRun.annotations` strictly conforming to the `RunAnnotations` schema from `trigger.dev/core/v3`. If the code already uses `RunAnnotations.safeParse` (e.g., in a `#parseAnnotations` helper), treat that as intentional/necessary for atomic, schema-accurate annotation handling. Do not recommend relaxing the annotation payload schema or using a permissive “passthrough” parse path, since the annotations are expected to be written atomically in one operation and should not contain partial/legacy payloads that would require a looser parser.

Applied to files:

  • apps/webapp/app/services/platformNotifications.server.ts
🔇 Additional comments (10)
apps/webapp/app/services/platformNotifications.server.ts (6)

62-70: LGTM!

The rename from hideArchived to hideInactive with the updated filter logic (archivedAt: null AND endsAt > now) correctly captures both archived and expired notifications for hiding.


103-118: LGTM!

Good additions exposing scope foreign keys and parsed payload fields for the admin list. The fallback defaults (false for dismissOnAction, null for discovery) when parsing fails are sensible.


323-362: LGTM!

The updated getRecentChangelogs correctly:

  1. Requires userId and filters by startsAt <= now to hide future changelogs
  2. Applies scope filtering to prevent user-scoped changelogs leaking to others
  3. Conditionally adds ORGANIZATION/PROJECT scope filters only when IDs are provided

This addresses the PR objective to show changelogs to the target audience.


557-573: LGTM!

Extracting NotificationBaseFields as a reusable const object is a clean DRY refactor, and using a const object instead of an interface aligns with the coding guidelines.


685-700: LGTM!

The UpdatePlatformNotificationSchema correctly reuses NotificationBaseFields, makes startsAt required (unlike create), and appropriately skips validateStartsAt since existing notifications may have past start dates.


743-779: LGTM!

The updatePlatformNotification function correctly:

  1. Nullifies scope FKs when scope changes (lines 762-764)
  2. Nullifies CLI-only fields when surface is not CLI (lines 768-770)
  3. Reuses the CreateError type for consistent error handling via neverthrow
apps/webapp/app/components/navigation/HelpAndFeedbackPopover.tsx (1)

33-46: LGTM!

The component correctly accepts optional organizationId and projectId props and passes them to useRecentChangelogs for context-aware changelog filtering. The props are appropriately optional to maintain backward compatibility.

apps/webapp/app/components/navigation/OrganizationSettingsSideMenu.tsx (1)

207-209: LGTM!

Correctly passes organizationId to HelpAndFeedback in the organization settings context. Omitting projectId is appropriate here since this menu is at the organization level, not scoped to a specific project.

apps/webapp/app/components/navigation/SideMenu.tsx (2)

716-716: LGTM!

Correctly passes both organizationId and projectId to HelpAndAI in the project-scoped side menu context, enabling full context-aware changelog filtering.


1166-1181: LGTM!

The HelpAndAI component correctly:

  1. Accepts organizationId and projectId as required props (appropriate since it's always rendered with both in SideMenu)
  2. Forwards them to HelpAndFeedback

@0ski 0ski merged commit 3c9647c into main Apr 13, 2026
41 checks passed
@0ski 0ski deleted the oskar/feat-platform-notifications-admin branch April 13, 2026 10:26
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