Skip to content

Commit 6e6e5bc

Browse files
authored
docs: apply 23 doc-review findings from 2-week diff scan (2026-05-22) (#60)
Phase-2 fixes derived from automated /doc-review --mode diff --since "2 weeks ago" --auto run. Scanned 11 source repos, produced 24 findings (10 high, 6 medium, 8 low), applied 23 to docs (1 low-priority miniprogram stack-URL normalization deferred). Module-by-module changes: on-call (3 findings on noise-reduction.mdx + 1 each on what-is-incident.mdx, alert-pipelines.mdx): - New 事件聚合 / Event Aggregation section (per-channel event→alert merge window; default 24h, 1–1440 min, can be disabled) - New 到期后自动删除 toggle for 单次静默 rules (24h auto-cleanup, mirrors quick-silence behavior) - New 隐藏/展示 Meta Label toggle on incident detail page (filters /^__.*__$/ labels, persisted per user) - FAQ rewrite to disambiguate event→alert vs alert→incident merge windows - Cross-ref Tip from alert-pipelines.mdx to 事件聚合 on-call/integration: - NEW page http-pull.mdx documenting the pull-based HTTP alert source (URL/method/headers/body, timeout 1–300s, retry 0–10, cycle ≥30s, cursor pagination, severity_mapping with P1/P2/P3 defaults, {{.PageValue}} template var) statuspage: - Native one-click unsubscribe (RFC 8058 List-Unsubscribe headers) on subscriptions.mdx - --url-name slug/uniqueness rules + create-only semantics + conflict-error guidance on migrate-from-atlassian.mdx - Rewrote 时间线更新 invariants on publish-events.mdx (monotonic ≥ rule, middle-edit bounds, first-entry start_time resync, maintenance auto-schedule reschedule) platform: - New Custom menu permission scope + system-vs-account dynamic permission model on permission-design.mdx - New force_sso toggle (default-on, no owner bypass, account-switch lockout warning) on configure-sso.mdx rum: - NEW page rum/analytics/miniprogram.mdx covering the WeChat miniprogram Dashboard (Overview + Performance with 5 metrics, trend modes, cold/warm-start breakdown, sample distribution, page-detail table) - source-mapping.mdx: documented sourcemap.zip layout (__FULL__ / subpackage / .js.map suffix), size limits (50 MB entry / 500 MB aggregate / 5000 entries), --appid parameter (removed the now-incorrect "not supported" note + added AppID ParamField + added column to source list), FAQ for ErrorMessage-as-stack fallback - erro-reporting/web.mdx: added 'app' / 'promise' to error.source enumeration with cross-link to miniprogram SDK - explorer/overview.mdx: documented platform-aware view metrics (Browser/Native/Miniprogram) - explorer/data-query.mdx: documented 7 queryable miniprogram view.* fields - quickstart/app-management.mdx: documented in-product miniprogram SDK config assistant (env/service/version/sessionSampleRate constraints + flow) - Renamed npm package @flashcatcloud/miniprogram-rum → @flashcatcloud/fc-sdk-miniprogram across all 4 wechat-miniprogram SDK pages (matches what the in-product card hands to users) developer: - Corrected MCP Server tool inventory on overview.mdx (was "18 tools across 6 modules", now "22 tools across 8 modules") and added Alerts + Templates rows docs.json: registered the 2 new pages (http-pull.mdx, miniprogram.mdx) in their respective navigation groups for both zh and en. Skipped: - f011 (low, optional) — miniprogram stack-URL normalization (devtools/usr/cache-busting prefix stripping); behavioral detail, agent recommended deferral. - f017 (low) — per-plan alert-rule count cap; needs decision on whether to home under monitors/ or platform/pricing.mdx. - f024 (low) — developer/mcp-server.mdx is an intentional redirect to GitHub; no doc body to update.
1 parent cca986f commit 6e6e5bc

39 files changed

Lines changed: 1213 additions & 56 deletions

docs.json

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -193,6 +193,7 @@
193193
"expanded": false,
194194
"pages": [
195195
"zh/on-call/integration/alert-integration/alert-sources/standard alert",
196+
"zh/on-call/integration/alert-integration/alert-sources/http-pull",
196197
"zh/on-call/integration/alert-integration/alert-sources/prometheus",
197198
"zh/on-call/integration/alert-integration/alert-sources/grafana",
198199
"zh/on-call/integration/alert-integration/alert-sources/zabbix",
@@ -314,7 +315,8 @@
314315
"icon": "chart-pie",
315316
"pages": [
316317
"zh/rum/analytics/web",
317-
"zh/rum/analytics/native"
318+
"zh/rum/analytics/native",
319+
"zh/rum/analytics/miniprogram"
318320
]
319321
},
320322
{
@@ -1156,6 +1158,7 @@
11561158
"expanded": false,
11571159
"pages": [
11581160
"en/on-call/integration/alert-integration/alert-sources/standard alert",
1161+
"en/on-call/integration/alert-integration/alert-sources/http-pull",
11591162
"en/on-call/integration/alert-integration/alert-sources/prometheus",
11601163
"en/on-call/integration/alert-integration/alert-sources/grafana",
11611164
"en/on-call/integration/alert-integration/alert-sources/zabbix",
@@ -1277,7 +1280,8 @@
12771280
"icon": "chart-pie",
12781281
"pages": [
12791282
"en/rum/analytics/web",
1280-
"en/rum/analytics/native"
1283+
"en/rum/analytics/native",
1284+
"en/rum/analytics/miniprogram"
12811285
]
12821286
},
12831287
{

en/developer/overview.mdx

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -54,16 +54,18 @@ See the [Command-line tool](/en/developer/cli) guide for the full installation m
5454

5555
## MCP Server
5656

57-
The Flashduty MCP Server implements the [Model Context Protocol](https://modelcontextprotocol.io/), providing AI tools with 18 tools across 6 functional modules:
57+
The Flashduty MCP Server implements the [Model Context Protocol](https://modelcontextprotocol.io/), providing AI tools with 22 tools across 8 functional modules:
5858

5959
| Module | Tools | Capabilities |
6060
|--------|-------|-------------|
6161
| Incidents | 8 | Query, create, acknowledge, close incidents; view timelines and associated alerts; find similar incidents |
62+
| Alerts | 1 | Query the upstream raw event stream that produced a single alert (e.g. each Prometheus firing) |
6263
| Changes | 1 | Query change records |
6364
| Status Page | 4 | Query status pages, create events, update timelines |
6465
| Users & Teams | 2 | Query members and team information |
6566
| Channels | 2 | Query channels and escalation rules |
6667
| Custom Fields | 1 | Query custom field definitions |
68+
| Templates | 4 | Fetch preset channel templates, validate and preview template rendering, list available template variables and functions |
6769

6870
Three deployment modes are available:
6971

en/on-call/channel/noise-reduction.mdx

Lines changed: 39 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -44,15 +44,15 @@ Monitoring System → Event → Alert → Incident
4444
| Object | Definition | Source |
4545
| :----- | :--------------------------- | :------------------ |
4646
| **Event** | Raw notification from monitoring system, each trigger or recovery is an event | Zabbix, Prometheus, etc. |
47-
| **Alert** | Automatically triggered by events, multiple events for the same alert merge into one alert | Automatically created by Flashduty |
47+
| **Alert** | Automatically triggered by events. Events sharing the same `alert_key` merge into one alert within the channel's **Event Aggregation** window | Automatically created by Flashduty |
4848
| **Incident** | Primary object processed by Flashduty, triggered by alerts or created manually | Auto-triggered or manually created |
4949

5050
<Note>
5151
**Key understanding**:
5252

53-
- One alert can contain multiple events (same alert's triggers, recoveries)
53+
- One alert can contain multiple events (events with the same `alert_key` that arrive within the Event Aggregation window, plus the corresponding recovery events)
5454
- One incident can contain multiple alerts (similar alerts grouped together)
55-
- Noise reduction occurs at the "Alert → Incident" stage
55+
- Noise reduction happens at two stages: **Event Aggregation** controls "Event → Alert"; **Alert Grouping** controls "Alert → Incident"
5656
</Note>
5757

5858
## Noise Reduction Process
@@ -78,6 +78,34 @@ When a monitoring system pushes alerts to Flashduty On-call, the system automati
7878
![Alert Noise Reduction Flowchart](https://download.flashcat.cloud/flashduty/doc/en/fd/aggr-3.png)
7979
</Frame>
8080

81+
## Event Aggregation
82+
83+
Go to Channel Details → **Noise Reduction****Event Aggregation** to configure.
84+
85+
Event Aggregation controls the "Event → Alert" merge behavior: when the upstream monitoring system keeps pushing events that share the same `alert_key`, whether those events are merged into the same existing alert or each one creates its own independent alert.
86+
87+
<Note>
88+
New channels have Event Aggregation enabled by default, with a window of **24 hours** (1440 minutes).
89+
</Note>
90+
91+
### Configuration
92+
93+
| Configuration | Description | Default | Range |
94+
| :--- | :--- | :--- | :--- |
95+
| **Enable Event Aggregation** | When enabled, events with the same `alert_key` merge into the same alert within the aggregation window; when disabled, every event creates its own alert | Enabled | Enabled / Disabled |
96+
| **Aggregation Window** | Starts counting from the alert's creation time; events arriving after this duration create a new alert. Only configurable when Event Aggregation is enabled | 1440 minutes (24 hours) | 1–1440 minutes |
97+
98+
<Tip>
99+
`alert_key` is the identifier used for alert correlation and deduplication. It is either reported by the upstream integration or generated automatically by integration rules.
100+
</Tip>
101+
102+
### Versus Alert Grouping
103+
104+
| Stage | Setting | Behavior it controls |
105+
| :--- | :--- | :--- |
106+
| **Event → Alert** | Event Aggregation | Whether events sharing the same `alert_key` merge into a single alert |
107+
| **Alert → Incident** | Alert Grouping | Whether similar alerts merge into a single incident |
108+
81109
## Alert Grouping
82110

83111
Go to Channel Details → **Noise Reduction** to configure.
@@ -241,6 +269,8 @@ Go to Channel Details → Noise Reduction → **Silence Rules**.
241269
- You can also pick the start and end directly on the right; the duration input updates accordingly.
242270
- Start time must be earlier than end time, and neither field may be empty.
243271

272+
**Auto-delete on expiration** (`is_auto_delete`): one-time silence rules can opt into this switch. When enabled, the rule is automatically removed by the system 24 hours after its end time, matching the cleanup behavior of [Quick Silence](#quick-silence). When disabled (the default), the rule stays in the list after expiration but is no longer active — you can keep it for reuse or delete it manually.
273+
244274
### Silence Conditions
245275

246276
Define which alerts should be silenced, supports multiple condition combinations.
@@ -351,8 +381,12 @@ When a new alert meets the conditions and there is a matching **active alert** (
351381
Up to 5000, mainly to ensure console rendering performance. Due to backend concurrent processing, actual count may slightly exceed this limit.
352382
</Accordion>
353383
<Accordion title="What's the maximum number of events a single alert can be associated with?" icon="circle-question">
354-
- **Rule-based grouping / Intelligent grouping**: No limit, default maximum aggregation window is 24 hours; rule-based and intelligent grouping share the same cap and can be extended to 30 days on request (contact the Flashduty team to enable). After exceeding the window, new events create new incidents
355-
- If the aggregation window is disabled, alerts continue merging into the existing incident until the incident is closed, with no time limit
384+
Whether an event can merge into an existing alert is controlled by the channel's **Event Aggregation** setting (which governs the "Event → Alert" stage — enabled by default with a 24-hour window, configurable from 1 to 1440 minutes, or can be turned off entirely):
385+
386+
- **Event Aggregation enabled**: events with the same `alert_key` merge into the same alert within the window; events arriving after the window expires create a new alert
387+
- **Event Aggregation disabled**: every event creates an independent alert, with no merging
388+
389+
Note that **Alert Grouping** controls the merge window at the "Alert → Incident" stage (24 hours by default, extendable to 30 days). It is a separate concern from whether events merge into an alert — don't conflate the two.
356390
</Accordion>
357391
</AccordionGroup>
358392

en/on-call/incident/what-is-incident.mdx

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,18 @@ Alert labels are extracted from event messages reported by the original monitori
6363

6464
Flashduty On-call provides label enhancement for automatic label generation. Go to [Configure Label Enhancement](/en/on-call/integration/alert-integration/label-enhancement) to learn more.
6565

66+
### Hide Meta Labels
67+
68+
The label panel on the incident/alert details page provides a **Hide Meta Label** / **Show Meta Label** toggle that filters out internal labels whose name starts and ends with `__` (Prometheus-style meta labels, such as `__instance__` or `__name__`).
69+
70+
- The button only appears when the current incident or alert actually contains meta labels
71+
- The toggle state is saved as a **per-user preference** that persists across sessions and devices; the mobile app and the web console share the same preference
72+
- When meta labels are hidden, the JSON view, formatted view, copy action, and drag-to-reorder all operate on the filtered label set
73+
74+
<Tip>
75+
When integrating with Prometheus, Nightingale, or other sources that emit a lot of internal labels, we recommend hiding meta labels by default so the label panel stays focused on business dimensions.
76+
</Tip>
77+
6678
## Incident Lifecycle
6779

6880
<Steps>

en/on-call/integration/alert-integration/alert-pipelines.mdx

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,10 @@ Since label enhancement runs before Pipeline, Pipeline match conditions **can re
3232
Recovery events (event_status is Ok) bypass the alert processing Pipeline entirely and go directly into the alert merge flow. Therefore, discard, inhibition, rewrite, and other rules configured in Pipeline do not apply to recovery events.
3333
</Note>
3434

35+
<Tip>
36+
After an event passes through the Pipeline, whether it merges into an existing alert is determined by the target channel's **Event Aggregation** setting (24-hour window by default, configurable from 1 to 1440 minutes, or can be turned off). See [Noise Reduction - Event Aggregation](/en/on-call/channel/noise-reduction#event-aggregation) for details.
37+
</Tip>
38+
3539
## How It Works
3640

3741
Pipeline sits between **Label Enhancement** and **Route Distribution**. Its execution logic is as follows:
Lines changed: 113 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,113 @@
1+
---
2+
title: "HTTP Pull Alert Integration"
3+
description: "Flashduty periodically polls an external HTTP endpoint and ingests the returned alert events. Use this for systems that cannot push alerts, or when you prefer to decouple ingestion from the source."
4+
keywords: ["Alert Integration", "HTTP Pull", "Polling", "Cursor Pagination", "Data Ingestion"]
5+
---
6+
7+
By configuring an HTTP endpoint, Flashduty issues a request on the schedule you define and parses the response into events conforming to the [Standard Alert Event](/en/on-call/integration/alert-integration/alert-sources/standard%20alert) protocol, which are then written into the alert channel. Your system does not need to support push delivery — it only needs to expose a readable alert query endpoint.
8+
9+
:::tips
10+
HTTP Pull is the right choice when your source **cannot send webhooks**, **is query-only by nature**, or when you **do not want to modify the upstream system**. If your system already supports webhook delivery, prefer the corresponding push-based integration (Prometheus, Zabbix, etc.) — it has lower latency and a smaller resource footprint.
11+
:::
12+
13+
## Setup Steps
14+
---
15+
16+
### In Flashduty
17+
18+
<details>
19+
<summary>Using Dedicated Integration</summary>
20+
21+
When you don't need to route alert events to different channels, this method is preferred — it's simpler.
22+
23+
1. Enter the Flashduty console, select **Channel**, and enter the details page of a channel.
24+
2. Select the **Integrations** tab, click **Add Integration** to enter the add integration page.
25+
3. Select the **HTTP Pull** integration.
26+
4. Fill in the form as described in the "Configuration" section below and click **Save**.
27+
</details>
28+
29+
<details>
30+
<summary>Using Shared Integration</summary>
31+
32+
When you need to route alert events to different channels based on the alert payload, choose this method.
33+
34+
1. Enter the Flashduty console, select **Integration Center => Alert Events** to enter the integration selection page.
35+
2. Select the **HTTP Pull** integration and fill in the **Integration Name**.
36+
3. Configure the **Default Route** and select the corresponding channel (after the integration is created, go to **Route** to add finer-grained routing rules).
37+
4. Fill in the form as described in the "Configuration" section below and click **Save**.
38+
</details>
39+
40+
## Configuration
41+
---
42+
43+
### HTTP Request
44+
45+
| Field | Required | Default | Description |
46+
| :-: | :-: | :-: | :--- |
47+
| URL | Yes | - | The target URL to poll. Must start with `http` or `https`. Supports Go template variables — see "Template Variables" below. Example: `https://example.com/api/alerts?cursor={{.PageValue}}`. |
48+
| Method | Yes | `GET` | Only `GET` or `POST` is supported. |
49+
| Headers | No | - | Key-value list, typically used to carry auth (`Authorization`, `X-Api-Key`, etc.). |
50+
| Body | Required when method is `POST` | - | Arbitrary string, typically JSON. When cursor pagination is enabled and **Inject To** is `Body`, the body **must** contain the `{{.PageValue}}` placeholder, e.g. `{"cursor":"{{.PageValue}}"}` — otherwise form validation fails. |
51+
| Timeout (seconds) | Yes | `10` | Timeout for a single HTTP request, range `1 ~ 300`. |
52+
| Retry Count | Yes | `0` | Number of retries on a single failed request, range `0 ~ 10`. |
53+
| Polling Cycle (seconds) | Yes | `60` | Interval between successive polls. **Minimum 30 seconds.** |
54+
55+
### Pagination
56+
57+
Many query-style endpoints cap the number of records returned per call and require cursor-based pagination to walk through the full result set. Flashduty supports cursor pagination: on each response it extracts the next-page cursor, injects it into the next request, and repeats until the cursor is missing or the page cap is reached.
58+
59+
| Field | Required | Default | Description |
60+
| :-: | :-: | :-: | :--- |
61+
| Pagination Mode | Yes | `None` | `None`: stop after a single request; `Cursor`: enable cursor-based pagination. |
62+
| Cursor Path | Required when pagination is on | - | Dot-delimited path used to extract the next-page cursor from the response JSON, e.g. `pagination.next_cursor`. |
63+
| Inject To | Required when pagination is on | `URL Query` | Where to place the cursor on the next request. `URL Query`: append as a query parameter; `Body`: merge into the request body. Forced to `URL Query` when the method is `GET`. |
64+
| Param Name | Required when Inject To is `URL Query` | - | The query-string parameter name used to carry the cursor, e.g. `cursor`. When **Inject To** is `Body`, the parameter name is whatever your body template specifies — no separate value is needed here. |
65+
| Max Pages | Required when pagination is on | `20` | Maximum pages to walk per polling cycle, range `1 ~ 100`. Pagination stops once the cap is hit or no next-page cursor can be extracted from the response. |
66+
67+
### Severity Mapping
68+
69+
External systems use different field names and values for alert severity. **Severity Mapping** translates the external value into Flashduty's standard `Critical / Warning / Info`.
70+
71+
- Flashduty reads the `event_status` field from each event in the response (the severity field defined by the Standard Alert Event protocol) and looks it up in the mapping table to find the corresponding Flashduty severity.
72+
- **Default mapping**: `P1 → Critical`, `P2 → Warning`, `P3 → Info`. You may remove the defaults or add any number of custom entries.
73+
- **Fallback when no match**: if the `event_status` value does not match any key in the mapping, it falls back to `Warning`.
74+
75+
### Response Format
76+
77+
The response must conform to Flashduty's [Standard Alert Event](/en/on-call/integration/alert-integration/alert-sources/standard%20alert) protocol (`response_mode = standard`). Key fields include `event_status`, `title_rule`, `alert_key`, `description`, `labels`, etc. Refer to the Standard Alert Event documentation for the semantics and length limits of each field.
78+
79+
When pagination is enabled, the response must additionally expose a field for the next-page cursor, located at the path you set in **Cursor Path**. A typical shape:
80+
81+
```json
82+
{
83+
"alerts": [
84+
{ "event_status": "Critical", "title_rule": "cpu idle low than 20%", "alert_key": "host-1" },
85+
{ "event_status": "Warning", "title_rule": "disk usage > 80%", "alert_key": "host-2" }
86+
],
87+
"pagination": {
88+
"next_cursor": "eyJvZmZzZXQiOjEwMH0="
89+
}
90+
}
91+
```
92+
93+
## Default Route
94+
---
95+
96+
When creating a "Shared Integration" (under **Integration Center => Alert Events**), you must configure a default route — otherwise newly pulled events will be dropped. After creation, you can add finer-grained rules under **Route**.
97+
98+
A "Dedicated Integration" (created under the **Integrations** tab of a specific channel) is automatically bound to that channel and does not need a separate default route.
99+
100+
## Template Variables
101+
---
102+
103+
The URL and request body support Go template syntax. There is currently **one** built-in variable:
104+
105+
| Variable | Description |
106+
| :-: | :--- |
107+
| `{{.PageValue}}` | The pagination cursor value to send on the current request. **It is an empty string on the first request**; every subsequent request renders the variable with the value extracted from the previous response using **Cursor Path**. |
108+
109+
Usage rules:
110+
111+
- When cursor pagination is enabled, `{{.PageValue}}` must appear at least once in the URL (when **Inject To** is `URL Query`) or the body (when **Inject To** is `Body`) — otherwise the next-page cursor cannot take effect.
112+
- `GET` requests force **Inject To** to `URL Query`, but you still decide which query parameter the variable lives in, or you can use **Param Name** to let Flashduty append it for you.
113+
- When pagination is `None`, the variable always renders as an empty string.

en/on-call/statuspage/migrate-from-atlassian.mdx

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -82,7 +82,19 @@ flashduty statuspage migrate structure \
8282
| `--from` | Yes | Migration source, currently only `atlassian` |
8383
| `--source-page-id` | Yes | Atlassian Statuspage Page ID |
8484
| `--api-key` | Yes | Atlassian Statuspage API Key |
85-
| `--url-name` | No | URL name for the newly created Flashduty public status page |
85+
| `--url-name` | No | URL name for the newly created Flashduty public status page. See constraints below |
86+
87+
<Warning>
88+
`--url-name` is honored **only when this run creates a new target status page.** If the same `--source-page-id` is already mapped to an existing Flashduty status page from a previous migration:
89+
90+
- Omit `--url-name`, or pass a value that **exactly matches** the existing target's URL name — the migration reuses that target and continues.
91+
- Pass a value that **differs** from the existing target's URL name — the migration fails synchronously during preflight with an error of the form `url_name only applies when creating a new target page; source page <src> is already mapped to target page <id> with url_name "<existing>", but requested "<new>"`. To change the URL name, edit the target status page directly in the Flashduty console.
92+
</Warning>
93+
94+
Format and uniqueness requirements for `--url-name`:
95+
96+
- Normalized by `MakeSlug`: lowercased, hyphen-separated, capped at 255 characters. Pure-symbol input or anything that normalizes to an empty string is rejected with `url_name must not be empty after normalization`.
97+
- **Globally unique** across the account's public status pages. Collisions are rejected with `url_name must be unique`.
8698

8799
Migration jobs run asynchronously -- the command returns immediately with a **Job ID**.
88100

0 commit comments

Comments
 (0)