Skip to content

Per-page alert control: a page silenced by unsubscribe cannot be un-silenced #112

Description

@georgekaran

Context

Issue #21 listed "alert threshold" among the page detail controls. It came out of that issue's scope because there is nothing to build it against: the control implies per-page alert settings, and the data model has only half of one.

What exists today:

  • accounts.alert_threshold — per account, on the wire in AccountResponse, and the only threshold detection reads.
  • pages.alerts_enabled — per page, added by migration 008, selected in postgres-page-repository.ts, and set to false by the unsubscribe token flow. It is not in PageModel, not in @tabstop/contract, and not settable through the API.
  • PATCH /api/pages/:id accepts monitoringEnabled and nothing else.

So a page can be silenced by clicking unsubscribe in an email, and then never un-silenced from the product. That is the actual bug hiding behind the missing control.

Scope

In

  • Expose alertsEnabled on the page wire types and let PATCH /api/pages/:id set it.
  • A per-page alerts toggle on page detail, beside pause and remove, so a page silenced by an unsubscribe link can be turned back on.
  • Say what the toggle means: pausing stops the audits, silencing stops the emails. Per DECISIONS.md these are deliberately different actions and the UI should not blur them.

Out

  • A per-page threshold override. There is no column for it, and it is a larger question than a control: whether the threshold belongs to the account, the page, or both, and what happens to detection when they disagree. Worth its own issue if the demand appears.
  • Any change to detection, to the dispatcher, or to the unsubscribe token.

Implementation sketch

Server, mirroring how monitoringEnabled already flows:

  • PageModel gains alertsEnabled; the mapper already selects the column.
  • PageView in contract/src/pages.ts gains alertsEnabled: boolean.
  • updatePageSchema gains an optional strict boolean — optional, so an existing client sending only monitoringEnabled keeps working, and strict for the reason already recorded there: z.coerce.boolean() maps "false" to true.

Web:

  • The toggle sits in the page controls and reuses the row-scoped optimistic pattern from useSetPageMonitoring, including the rollback that restores only the affected page.

The two states are independent, and all four combinations are reachable: monitored and alerting, monitored and silent, paused and alerting (which sends nothing, because nothing is audited), paused and silent. The copy has to make the first two distinguishable at a glance, since that is the pair a reader will actually be choosing between.

Acceptance criteria

  • alertsEnabled is on the page wire types and settable through PATCH /api/pages/:id.
  • A page silenced through an unsubscribe link can be re-enabled from the product.
  • The toggle says what it changes, and does not read as pausing monitoring.
  • Sending only monitoringEnabled still works.

Split out of #21.

Metadata

Metadata

Assignees

No one assigned

    Labels

    area:webFrontend under web/

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions