Skip to content

fix: orphaned monitor page components#1911

Merged
mxkaske merged 3 commits intomainfrom
fix/orphaned-monitor-page-components
Mar 3, 2026
Merged

fix: orphaned monitor page components#1911
mxkaske merged 3 commits intomainfrom
fix/orphaned-monitor-page-components

Conversation

@mxkaske
Copy link
Member

@mxkaske mxkaske commented Mar 3, 2026

No description provided.

@vercel
Copy link

vercel bot commented Mar 3, 2026

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

Project Deployment Actions Updated (UTC)
openstatus-dashboard Ready Ready Preview, Comment Mar 3, 2026 8:13am
openstatus-status-page Ready Ready Preview, Comment Mar 3, 2026 8:13am
openstatus-web Ready Ready Preview, Comment Mar 3, 2026 8:13am

Request Review

Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

This PR addresses “orphaned” status page components that reference monitors after monitors are deleted (soft-deleted), and adjusts page component limit enforcement to validate the requested target state rather than the existing state.

Changes:

  • Validate pageComponent.updateOrder against the incoming total component count (including grouped components) instead of blocking based on current DB count.
  • On monitor deletion (single and bulk), delete pageComponent rows referencing the deleted monitor(s) to avoid orphaned components.
  • Add equivalent page component cleanup to the server RPC DeleteMonitor implementation.

Reviewed changes

Copilot reviewed 3 out of 3 changed files in this pull request and generated 5 comments.

File Description
packages/api/src/router/pageComponent.ts Enforces page component limits based on the incoming “new” component count.
packages/api/src/router/monitor.ts Deletes monitor-linked pageComponent rows during monitor delete / bulk delete.
apps/server/src/routes/rpc/services/monitor/index.ts Cleans up related junction tables and pageComponent rows on RPC monitor deletion.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment on lines +160 to +166
// Validate the incoming component count against the limit
const newComponentCount =
opts.input.components.length +
opts.input.groups.reduce((sum, g) => sum + g.components.length, 0);

if (newComponentCount > pageComponentLimit) {
throw new TRPCError({
Copy link

Copilot AI Mar 3, 2026

Choose a reason for hiding this comment

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

The new limit validation changes behavior but there’s no test covering the boundary cases (exactly at the limit should succeed; exceeding the limit via components+group components should throw). Please add/adjust tests for pageComponent.updateOrder to lock in this logic and prevent regressions.

Copilot uses AI. Check for mistakes.
Comment on lines 136 to 141
.delete(maintenancesToMonitors)
.where(inArray(maintenancesToMonitors.monitorId, opts.input.ids));
await tx
.delete(pageComponent)
.where(inArray(pageComponent.monitorId, opts.input.ids));
});
Copy link

Copilot AI Mar 3, 2026

Choose a reason for hiding this comment

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

Same atomicity concern as the single-delete path: the soft-delete update is executed before the cleanup transaction. Wrapping both the monitor update and the related deletes in one transaction would avoid partially-applied deletions if the cleanup fails.

Copilot uses AI. Check for mistakes.
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