<!--A few plain bullets saying what changed and why, for a reviewer
skimming it - not a wall of text, not a restatement of the diff, not
generated boilerplate.-->
#### Description
This PR adds one endpoint, `POST /api/v2/notification_channels`, whose
typed `{name, displayName, config:{kind, spec}}` body replaces v1's
pass-through Alertmanager receiver JSON. v1 routes are deliberately
untouched, so the diff is near-purely additive.
List/get/update/delete/test come in the next PR.
<!--Reference issues using `Closes #issue-number` to enable automatic
closure on merge. -->
#### Issues closed by this PR
Closes https://github.com/SigNoz/pulse-pod/issues/296
<!--Anything reviewers should keep in mind while reviewing -->
Eventually references (rules, routing policies) migrate onto
internal_name, freeing name to become a user-editable display name. But
that will happen post rules migration so that all rules are on v2
<!--Please delete paragraphs that you did not use before submitting.-->
#### Description
- Adds a `subscription` domain: `POST`, `PUT`, and `GET
/api/v1/subscriptions`, wired with `CheckResources` + `ResourceDef`s on
the `subscription` metaresource (`create`, `list` + `update`, `read`).
Community gets a noop implementation; enterprise talks to Zeus.
- Migration `125_add_subscription_tuples` backfills the admin
subscription tuples for existing organizations.
- The legacy `/api/v1/checkout`, `/api/v1/billing`, and `/api/v1/portal`
routes are untouched; they are deleted once the frontend has moved.
#### Additional Information
Part of SigNoz/platform-pod#3091.
#### Description
- Moves all ingestion key and limit routes from the legacy `EditAccess`
gate to `CheckResources` + `ResourceDef`s (kinds `ingestion-key` /
`ingestion-limit`) with scoped security schemes.
- Limit create checks `create` on the limit plus `attach` on the parent
key; limit delete checks `delete` plus `detach`, resolving the parent
key via the new upstream get-limit call.
- Grants `attach`/`detach` on `ingestion-key` to the admin and editor
managed roles; migration 120 backfills all ingestion tuples for existing
organizations and refreshes the managed roles' `transaction_groups`.
Stacked on #12625.
#### Issues closed by this PR
ClosesSigNoz/platform-pod#2651
#### Additional Information
- Wiremock fixtures now use UUID key/limit IDs — the metaresource FGA
selector only accepts UUIDs.
- Delete requests make one extra upstream GET (parent-key resolution)
before the authz verdict, mirroring the serviceaccount extractor
pattern.
#### Description
The old API didn't support telemetryFieldKey, so adding a new v2 API to
support it.
This PR
* Migrates old data to the new one.
* Existing API's now internally stores it in the new struct so that they
don't break the UI.
<!--Reference issues using `Closes #issue-number` to enable automatic
closure on merge. -->
#### Issues closed by this PR
Closes https://github.com/SigNoz/engineering-pod/issues/5947
## Additional details
* the old api is safe with new field as it is just a subset of it.
#### Description
Adds support for related values in ai observability field values.
<!--Reference issues using `Closes #issue-number` to enable automatic
closure on merge. -->
#### Issues closed by this PR
Closes https://github.com/SigNoz/engineering-pod/issues/5975
#### Description
- Adds first-class ingestion limit APIs under
`/api/v2/gateway/ingestion_limits`: create (`keyId` in body), get,
update, and delete by `{limitId}`. Get proxies the new upstream `GET
/v1/workspaces/me/limits/{limitID}`.
- Adds key read APIs: `GET /api/v2/gateway/ingestion_keys/{keyId}` (key
by id — upstream does not embed limits here) and `GET
/api/v2/gateway/ingestion_keys/{keyId}/limits` (limits for a key, with
current-period usage metrics).
- Marks the existing limit routes (`POST
/ingestion_keys/{keyId}/limits`, `PATCH/DELETE
/ingestion_keys/limits/{limitId}`) as deprecated; they keep working
unchanged.
- Renames the old create body to `DeprecatedPostableIngestionKeyLimit`;
`PostableIngestionKeyLimit` is now the first-class body carrying
`keyId`. Handlers decode via `binding.JSON` and the create response is
`types.Identifiable`.
Part of SigNoz/platform-pod#2651.
#### Additional Information
- OpenAPI spec and the generated frontend client are regenerated; the UI
stays on the deprecated routes for now.
- Requires the upstream get-by-id endpoints from
SigNoz/opentelemetry-gateway#96 (merged and deployed).
## Description
Adds **incident.io** as a native alert notification channel, using
incident.io's HTTP alert source (Alert Events V2 API)
- A channel is configured with the alert source's **URL + token**; title
and description templates are prefilled with the same defaults as
Jira/JSM.
- Alerts fire and auto-resolve in incident.io; the description is
markdown (incident.io renders it natively) and carries the usual deep
links — **View in SigNoz, related logs, related traces**.
- All rule labels (severity, team, custom labels) are sent as
**metadata**, so users can map them to incident.io attributes and
route/escalate on them.
Notes and decisions for the reviewer (full details in the [discussion
ticket and doc](https://github.com/SigNoz/pulse-pod/issues/171)):
- **Dedup:** one incident.io alert per notification group, keyed by the
group key hash (same identity Jira uses). A resolve targets the same
key; re-fires after resolve correctly open a fresh alert — no key
rotation needed.
- **Repeat notifications are no-ops on incident.io** (it drops duplicate
firing events) — unlike Jira, we cannot append updated values to an open
alert; operators click through to SigNoz for current values.
- **Limits:** description capped client-side under incident.io's
documented 512 KB payload limit; retries only on 429/5xx (documented
limit: 120 events/min per source).
- **Channel-level metadata:** optional key-value pairs on the channel
config, merged into every event's metadata on top of the alert's labels
(channel wins on key clash — Opsgenie precedent). Values are
template-expanded; a value that fails to expand is sent raw with a
warning logged, so delivery never breaks on a bad template.
- Upstream alertmanager ships its own basic incident.io notifier — our
config **shadows it** so the SigNoz notifier (templates, dedup,
metadata) handles delivery.
- Frontend (channel form) follows in a stacked PR.
## Issues closed by this PR
ClosesSigNoz/pulse-pod#172
---------
Co-authored-by: Naman Verma <naman.verma@signoz.io>
#### Description
- Adds strongly typed `/api/v4/licenses` endpoints on the apiserver with
OpenAPI definitions: activate, list, get, refresh, delete, and `GET
/api/v4/licenses/active`.
- Wires resource authz (`license:create/list/read/update/delete`) via
`CheckResources`; `GET /active` is `OpenAccess` and never includes the
license key — the key is returned only by the FGA-gated get-by-id, so
orgs can grant `license:read` selectively. Migration 118 backfills
license tuples for existing orgs.
- Delete is allowed only for non-cloud licenses; licenses managed by
SigNoz Cloud are rejected.
- v4 responses are camelCase with lowercase enum values; v3 routes and
stored license data are unchanged.
#### Issues closed by this PR
Closes https://github.com/SigNoz/platform-pod/issues/3076
#### Description
Adds two Atlassian alert channels. Backend only — frontend is #12488;
channels are created via the API.
**Jira issues — `jira_configs`**
- A firing alert creates a Jira Cloud issue; when the alert resolves,
the issue is transitioned to done. A re-fire within 3 days reopens the
same issue instead of creating a new one. 3 days is default but can be
edited via frontend form.
- The issue body is rich **Atlassian Document Format (ADF)**: a status
panel, the rendered alert description, and deep-links back to SigNoz.
- Re-fires keep the issue in sync (summary and description are
refreshed), and every notification after the first — re-fire, resolve,
reopen — also posts a **comment** carrying the same rich ADF snapshot,
so the issue holds a full lifecycle timeline.
- Per-rule custom notification templates (title/body) are honored, same
as every other channel; multi-alert custom bodies render as
divider-separated sections.
- Auth is Atlassian email + API token; Atlassian **service accounts**
also work (routed via the `api.atlassian.com` gateway automatically —
the cloud id is resolved server-side and client-supplied values are
ignored). Jira Cloud only.
**JSM Ops alerts — `jsmops_configs`**
- A firing alert opens a JSM Operations alert (the ex-Opsgenie alert
product); resolve **closes** it. A fire after close opens a fresh alert
— there is no reopen window.
- Re-fires dedupe into the same alert and increment its count. The alert
description keeps the first-fire snapshot; the value-over-time story
lives in the notes.
- Every fire and the resolve appends a **note** to the alert. JSM Ops
notes support **plain text only** (they render neither HTML nor
markdown), so notes use a new plain-text renderer with links flattened
to `text (url)`.
- The alert description supports JSM's **HTML subset**, rendered from
the same markdown templates.
- Auth is the JSM integration API key. No region/site config needed.
**Also in this PR**
- Unit tests for both config types, both notifiers, and the new ADF +
plain-text renderers.
- OpenAPI spec regenerated (adds `jsmops_configs`).
#### Issues closed by this PR
ClosesSigNoz/pulse-pod#168 · Discussion: SigNoz/pulse-pod#169
#### Screenshots / Screen Recordings
Jira alert issue:
<img width="1171" height="739" alt="Screenshot 2026-08-18 at 12 49
31 PM"
src="https://github.com/user-attachments/assets/1ec74757-5d4d-4534-a5ca-13bed07cce72"
/>
Jira issue comments as a timeline:
<img width="1034" height="746" alt="Screenshot 2026-08-18 at 12 50
32 PM"
src="https://github.com/user-attachments/assets/09afb687-b62b-4eb3-86ab-39489e38513e"
/>
JSM Ops alerts page look:
<img width="1317" height="460" alt="Screenshot 2026-08-18 at 12 52
29 PM"
src="https://github.com/user-attachments/assets/dd5a60b5-ea6c-49b7-afde-f3b2c72b178a"
/>
JSM Ops alerts main body + comment timeline ( comments only support
plain text today ) :
<img width="1323" height="784" alt="Screenshot 2026-08-18 at 12 53
10 PM"
src="https://github.com/user-attachments/assets/871fb91c-307a-4c67-b2c4-bc9548506cbc"
/>
#### Additional Information
Notes for reviewers:
- Jira shadows upstream Alertmanager's `jira_configs` so our notifier
handles it instead of upstream's; this needs a small dedupe in
`PostableChannel.JSONSchema()` and leaves every other channel type
untouched.
- JSM Ops reuses the existing Opsgenie notifier; all new behaviour sits
behind a single `advancedFeatures` flag, so plain Opsgenie is unchanged
when it's off.
- `send_resolved` defaults off for both channels, so resolve-time
behaviour (Jira transition, JSM close + resolved note) needs it set on
the channel; the frontend will send it on by default.
- Notes are best-effort: a permanently-failed note (e.g. the first-fire
note racing JSM's asynchronous alert create) is dropped with a warning
instead of failing the whole notification. Nothing is lost — that first
datapoint is already in the alert body; retryable failures (429) still
retry.
---------
Co-authored-by: Naman Verma <naman.verma@signoz.io>
#### Description
Adding support for system dashboards.
* as of now updates are only through new versions in the file.
* user cannot update the dashboard
* For now kept the dashboard content empty and will raise it separately.
Closes https://github.com/SigNoz/engineering-pod/issues/4501
#### Description
- Adds `GET|POST /prometheus/api/v1/query_range` and
`/prometheus/api/v1/query` (`pkg/prometheus/promapi`), following the
Prometheus HTTP API contract: float-unix or RFC3339 times, float-seconds
or duration-string durations, the `{status, data, errorType, error,
warnings, infos}` envelope with Prometheus' status codes, and the
11,000-point cap.
- The `/prometheus` prefix works as a drop-in Prometheus base URL:
Grafana's Prometheus data source, promtool, and the PromQL compliance
tester append `/api/v1/*` to a base URL, so they can point at SigNoz
unmodified. Same layout as Mimir/Cortex.
- Wired through `signoz.Handlers` (`prometheus.Handler` interface,
constructed in `NewHandlers`) like the other domain handlers.
- Range queries serve through the `RangeExecutor` capability when the
provider has it, so a clickhousev2-serving deployment transpiles through
these endpoints too.
- New `promapiconformance` integration suite: the frozen promqltest
corpus replayed against these endpoints with `prometheus::provider:
clickhousev2` — the two paths nothing else exercises (v2 as serving
provider, and this API surface). Instant cases go through `/query` with
a real `time` parameter. The `instant-coarse` corpus variants are
skipped — they exist only to encode instant evals as coarse ranges for
the v5 API, and their transpiled coarse-step serving is already covered
and ledgered by promqlconformance's clickhousev2 leg — so this suite
asserts zero divergences with no ledger of its own.
- Purely additive: the existing `GET /api/v1/query_range` and `GET
/api/v1/query` handlers are untouched. `openapi.yml` is generated and
these mux-registered routes are outside the generator, so their
documentation is the upstream Prometheus API contract they follow.
#### Additional Information
Final slice of the clickhouseprometheusv2 stack (#12323, #12324, #12325
— merged). Legacy endpoint removal, if ever, is a separate change after
usage drains.
#### Description
- Deployment host routes (`GET`/`PUT /api/v2/zeus/hosts`) now use
`CheckResources` + `ResourceDef` instead of the coarse
`ViewAccess`/`AdminAccess` gates — per-resource FGA checks on
enterprise, role gate on community.
- New `deployment-host` metaresource kind with `list`/`update` verbs —
the GET returns the deployment's host collection and the PUT upserts the
single editable host. Admins get `list`+`update`, editors and viewers
get `list`, preserving current behavior.
- Migration `118_add_deployment_host_tuples` backfills the tuples for
existing organizations and re-syncs the stored managed-role transaction
groups; new organizations get both from the registry at bootstrap.
- Regenerated OpenAPI spec and transaction-groups schema: the operations
advertise `deployment-host:list`/`deployment-host:update` scopes instead
of `VIEWER`/`ADMIN`.
- Added `deploymenthost/01_authz.py` covering managed-role gating,
custom-role `list`/`update` grants, and rejection of verbs the resource
does not support.
#### Issues closed by this PR
ClosesSigNoz/platform-pod#2652
#### Description
- Changes `GET /api/v1/features` from `ViewAccess` to `OpenAccess` in
both editions so every authenticated user, including those on custom
roles, can read feature flags.
- Feature flags describe the org's plan, not the caller's privileges,
and the frontend needs them to boot. With #12700 making the active
license readable by every authenticated user, the flags must be readable
too — otherwise custom-role users load the license but hang on the flags
fetch.
- Applies the same change to the flagger endpoint `GET /api/v2/features`
so the v2 client behaves identically when the frontend migrates to it.
#### Issues closed by this PR
Closes: https://github.com/SigNoz/platform-pod/issues/2653
#### Description
* adds `ai_observability` to saved view for ai explorer
<!--Reference issues using `Closes #issue-number` to enable automatic
closure on merge. -->
#### Issues closed by this PR
Closes https://github.com/SigNoz/engineering-pod/issues/5955
#### Description
- Removes the deprecated `POST /api/v1/service_accounts/{id}/roles` and
`DELETE /api/v1/service_accounts/{id}/roles/{rid}` routes, their HTTP
handlers, and the `DeprecatedPostableServiceAccountRole` type, now that
all consumers use `/api/v1/service_account_roles`.
- Keeps the `GET /api/v1/service_accounts/{id}/roles` listing endpoint.
- Regenerates `docs/api/openapi.yml` and the frontend client.
#### Issues closed by this PR
Closes SigNoz/platform-pod#2919
#### Additional Information
- Final step of the migration; the frontend (#12589) and
integration-test (#12590) consumer moves are already merged.
#### Description
- Auth domain routes (`/api/v2/auth_domains`) now use `CheckResources` +
`ResourceDef` instead of the coarse `AdminAccess` gate — per-resource
FGA checks on enterprise, admin role gate on community.
- Create and update also check `attach` on the roles the request's
`roleMapping` will grant at SSO login (mapped roles + default role,
`signoz-viewer` when unset, `role:*` when `useRoleAttribute` is on);
update additionally checks `detach` on the roles the stored mapping was
granting, since a `PUT` replaces the mapping.
- Migration `117_add_auth_domain_tuples` backfills the admin
`auth-domain` tuples for existing organizations and re-syncs the stored
managed-role transaction groups; new organizations get both from the
registry at bootstrap.
- Regenerated OpenAPI spec: the auth-domain operations advertise
`auth-domain:*` and `role:attach`/`role:detach` scopes instead of
`ADMIN`.
- Added `callbackauthn/05_authz.py` covering managed-role gating,
custom-role wildcard/instance grants, and the role-mapping attach/detach
checks.
#### Issues closed by this PR
ClosesSigNoz/platform-pod#2649
## Pull Request
---
### 📄 Summary
- Add a `type` param to `/api/v1/fields/keys`; for type=builder_ai_query
(flag-gated) the metadata store returns the per-trace aggregate columns
(llm_call_count, input_tokens, …) as
trace-context keys — they're computed at query time, never ingested, so
the attribute scan can't serve them.
- Split `TraceColumn.Orderable` into `Orderable + Filterable`: ORDER BY
uses orderable, the trace-level filter validates against filterable, and
the API only returns keys that are both. `last_activity_time` is
order-only and now rejected in filters with a targeted error.**
- UI note: last_activity_time should be added to client-side list (it's
the default sort).
#### Issues closed by this PR
Part of https://github.com/SigNoz/engineering-pod/issues/5714
---
### ✅ Change Type
_Select all that apply_
- [x] ✨ Feature
- [ ] 🐛 Bug fix
- [ ] ♻️ Refactor
- [ ] 🛠️ Infra / Tooling
- [ ] 🧪 Test-only
---
### 🧪 Testing Strategy
> How was this change validated?
- Tests added/updated: ✅
- Manual verification: ✅
- Edge cases covered: ✅
---
### ⚠️ Risk & Impact Assessment
> What could break? How do we recover?
- Blast radius: None
- Potential regressions:
- Rollback plan:
#### Description
- Moves the endpoints to `/api/v2/auth_domains` and removes the
`/api/v1/domains` routes — the request/response shapes changed, so they
live behind new paths instead of breaking v1 in place.
- Restructures the auth domain payload: `config` is now a `{kind, spec}`
discriminated envelope (same pattern as `RuleThresholdData` /
`EvaluationEnvelope`), replacing the old `ssoType` discriminator with
`samlConfig` / `googleAuthConfig` / `oidcConfig` sibling fields;
`ssoEnabled` and `roleMapping` move to the root as `enabled` and
`roleMapping`.
- Renames the provider kind `google_auth` → `google`, and the SAML keys
to metadata-consistent ones: `samlEntity` → `entityId`, `samlIdp` →
`location`, `samlCert` → `certificate`.
- Migrates the persisted documents too: a new sqlmigration rewrites
`auth_domain.data` into `{enabled, config: {kind, spec}, roleMapping}`,
so all legacy-shape code (storable twins, `google_auth` translation,
per-kind conversion switches) is deleted; the remaining per-kind wiring
lives in a single variant registry that `UnmarshalJSON`,
`JSONSchemaOneOf` and the discriminator mapping derive from.
- `AuthDomain` exposes the domain shape (`Enabled()`, `Kind()`,
`Config()`, `RoleMapping()`, typed spec accessors) instead of the
persisted document; `config` presence is enforced explicitly on
Postable/Updatable (the old PUT path never enforced it and could poison
a row).
- Secret fields (`clientSecret`, `serviceAccountJson`) are `format:
password` in the schema, and `GoogleConfig` loses the unused
`redirectURI` (the migration strips it from persisted documents).
- Frontend: regenerated client is a clean discriminated union; both
directions of the envelope↔form translation live in
`CreateEdit.utils.ts` with an explicit kind→provider mapping (no
cross-enum casts).
- The generated OpenAPI spec carries a real `discriminator`; the
kind/spec envelope pattern itself is documented generically in #12494,
and this PR only keeps the auth domain worked example in `types.md` in
step with the refactored types.
- Updates the google authn integration tests (#12486) to the new API,
and adds parametrized POST→GET roundtrip cases pinning the response
contract per kind (server-side defaulting, role-name normalization, null
maps) plus enforcement-toggle update coverage.
#### Issues closed by this PR
ClosesSigNoz/platform-pod#2268
#### Additional Information
- Breaking change: `/api/v1/domains` is gone; the resource is now
`/api/v2/auth_domains` with the new shape. Login and SSO callback flows
are behaviorally unchanged, and existing rows are migrated in place at
startup.
- The `AuthNProvider` rename also surfaces in `/api/v2/sessions/context`
responses (`provider: "google"`) — the login page only consumes the
callback `url` — and in the reported stats key, which changes from
`authdomain.google_auth.count` to `authdomain.google.count`.
- Verified: `make go-test`, Go lint, frontend jest suites for
AuthDomain, `pnpm build`, `pnpm tsgo --noEmit`, and the full
`callbackauthn` domain suites (17 tests: roundtrip pins, the enforcement
toggle, and the google E2E flows) against a container rebuilt from this
branch — including a live run of the data migration over legacy-format
rows.
#### Description
- Removes the deprecated user endpoints that now have v2 replacements:
- `POST /api/v1/invite`, `GET /api/v1/user`, `GET
/api/v1/getResetPasswordToken/{id}`, `POST /api/v1/resetPassword`
- `POST /api/v2/users/{id}/roles` and `DELETE
/api/v2/users/{id}/roles/{roleId}`, superseded by `/api/v2/user_roles`
- `GET /api/v1/user/me` stays registered but returns 501 pointing at
`GET /api/v2/users/me`, following the v1 dashboard endpoints.
- Drops the handlers, module methods and types that only existed to
serve them (`DeprecatedUser`, the `user_invite` types, `PostableRole`).
- Moves the four remaining `*_cleanup` teardown tests off `DELETE
/api/v2/users/{id}/roles/{roleId}` onto `DELETE
/api/v2/user_roles/{id}`. Removal is keyed by the `user_role` entry id,
so they read it from `GET /api/v2/users/{id}` — that endpoint is not
deprecated and its other uses are untouched.
- Regenerates `docs/api/openapi.yml` and the frontend client. No
hand-written frontend code referenced the removed operations.
#### Issues closed by this PR
Closes: https://github.com/SigNoz/platform-pod/issues/2667
#### Additional Information
- `/api/v1/user/me` is a stub rather than a deletion because an
unregistered `/api/*` path falls through to the SPA catch-all and
answers 200 with `index.html`, which older mcp reads as a successful
response — a 501 fails loudly instead.
<!--A few plain bullets saying what changed and why, for a reviewer
skimming it - not a wall of text, not a restatement of the diff, not
generated boilerplate.-->
#### Description
- Adding GCP integration MySQL service
- Related fix: adding formula to convert CPU utilization fraction into
percentage for Postgres dashboard
<!--Reference issues using `Closes #issue-number` to enable automatic
closure on merge. -->
#### Issues closed by this PR
https://github.com/SigNoz/platform-pod/issues/2942
## Summary
- Handle malformed selectedFields in the extradata in the migration and
new migration to fix in the already migrated cases.
- Restructure saved-view create/update/get payloads so
`schemaVersion`/`spec` are top-level (unwrapping the old `data`
nesting), matching how dashboards and rules shape their wire types.
- Publish `schemaVersion` as an `enum: [v2]`
- Make `display` and `selectedFields` optional in the OpenAPI schema
- Declare `409` on `CreateSavedView`
- Require `minItems: 1` on `queries`
New API contract in [below
comment](https://github.com/SigNoz/signoz/pull/12477#issuecomment-5230041074),
follow up on https://github.com/SigNoz/signoz/pull/12342
Closes https://github.com/SigNoz/engineering-pod/issues/4651
Notes to reviewer:
- Please pay attention to the last case in above linked comment for
partial display field updates.
- Still assuming that [migration
046](6372af75a6/pkg/sqlmigration/046_update_dashboard_alert_and_saved_view_v5.go (L233))
has already migrated all the views to v5 QB format and don't need to do
that now.
- Breaking change: queries are not validated in the v1 APIs as well, so
any incorrect query will be rejected
---------
Co-authored-by: Claude Sonnet 5 <noreply@anthropic.com>
#### Description
- `POST /api/v1/resetPassword` was the last password endpoint with no v2
equivalent. Adds `POST /api/v2/factor_password/reset`, next to the
existing `/factor_password/forgot`, so the whole recovery flow lives
under one namespace.
- v1 keeps working and is now marked deprecated. Both routes share the
same handler, so behaviour is identical.
- A malformed request body now returns a structured 400 instead of a
500. This applies to v1 too, since the handler is shared.
#### Issues closed by this PR
Contributes to SigNoz/platform-pod#2667
#### Additional Information
- The generated frontend client is included because CI re-runs `pnpm
generate:api` and fails on drift. The UI still calls v1; moving it to
the new `useResetPassword` hook is a separate PR to keep review
ownership split.
- Not fixed here: a reset doesn't revoke existing sessions, though a
voluntary password change does. Worth its own ticket.
#### Description
- Removes `GET`, `PUT` and `DELETE /api/v1/user/{id}` — all deprecated
and superseded by `/api/v2/users/{id}`, which the frontend already uses.
- Drops the dead code this leaves behind: the `SelfAccess` middleware
and `Claims.IsSelfAccess` (no callers left), the deprecated update
setters, and three `DeprecatedUser` helpers.
- Points the integration tests that deleted users at `DELETE
/api/v2/users/{id}`.
#### Issues closed by this PR
Contributes to SigNoz/platform-pod#2667
#### Additional Information
- Behaviour change: the removed `GET`/`PUT` were `SelfAccess`, the v2
equivalents are `AdminAccess`. Self-serve reads and updates go through
`/api/v2/users/me`, which is what the UI already calls — but worth a
second pair of eyes.
- `DELETE /api/v1/user/{id}` was the most widely reached of the three.
Please confirm nothing external (zeus) still calls it before merging.
- OpenAPI spec and the generated frontend client are regenerated, not
hand-edited.
#### Description
- Removes `POST /api/v1/invite/bulk` — already deprecated, superseded by
`POST /api/v1/invite`, and no callers left.
- `Setter.CreateBulkInvite` stays; `CreateInvite` still delegates to it
for the single-invite case.
#### Issues closed by this PR
Contributes to SigNoz/platform-pod#2667
#### Additional Information
- OpenAPI spec and the generated frontend client are regenerated, not
hand-edited.
- The `integrationci / fmtlint` failure here is not from this PR — `make
py-lint` is broken on `main`. Fixed separately in #12475; this PR needs
that merged (or a rebase on it) to go green.
- First of three PRs splitting a v1 user-API cleanup. The other two also
regenerate the spec and generated client, so whichever merges second
needs the generators re-run.
## Pull Request
---
### 📄 Summary
Adds a `filterByPodStatus` secondary filter to the v2 infra-monitoring
list APIs (pods, nodes, namespaces, clusters, deployments, statefulsets,
jobs, daemonsets).
Pod status is a derived kubectl-style value (`k8s.pod.phase` + status
reasons, resolved via `argMax`), not a real label, so it can't go
through the normal query-builder filter. This PR resolves the full-scope
status keyset up-front and intersects it with the metadata + ranked
groups, keeping `total` and pagination correct.
- Multi-select: the field is an array, pushed down as `WHERE
lower(display_status) IN (...)` (OR within status, AND with the
attribute filter).
- When the optional status metrics were never ingested, the endpoint
returns a non-blocking warning + empty page instead of silently
filtering everything out.
#### Screenshots / Screen Recordings (if applicable)
N/A — backend + generated FE API types only; the UI is a separate
change.
#### Issues closed by this PR
Part of SigNoz/engineering-pod#5778.
---
### ✅ Change Type
- [x] ✨ Feature
- [ ] 🐛 Bug fix
- [x] ♻️ Refactor
- [ ] 🛠️ Infra / Tooling
- [ ] 🧪 Test-only
---
### 🐛 Bug Context
N/A — not a bug fix.
---
### 🧪 Testing Strategy
- Tests added/updated:
- Unit test for the status push-down (`applyPodStatusFilter`, built with
go-sqlbuilder).
- Integration tests across all 8 entity APIs: list mode, grouped mode,
validation, missing-metric warning, and multi-select union.
- Manual verification: smoke-tested against staging data (single, multi,
and grouped filters).
- Edge cases covered: missing status metric → warning + empty; grouped
mode keeps a group if ≥1 pod matches; multi-select returns the union of
the selected statuses.
---
### ⚠️ Risk & Impact Assessment
- Blast radius: v2 infra-monitoring list endpoints only.
- Potential regressions: none when the filter is unset (empty = off,
fully additive). When set, an extra status query runs; it is gated
behind the filter being present.
- Rollback plan: revert the PR — no schema or data migrations involved.
---
### 📝 Changelog
| Field | Value |
|------|-------|
| Deployment Type | OSS, Cloud, Enterprise |
| Change Type | Feature |
| Description | v2 infra-monitoring lists can now be filtered by pod
status (multi-select). |
---
### 📋 Checklist
- [x] Tests added or explicitly not required
- [x] Manually tested
- [x] Breaking changes documented
- [x] Backward compatibility considered
---
## 👀 Notes for Reviewers
- `filterByPodStatus` is optional and additive — no change to existing
responses when omitted.
- The status keyset is resolved once at full scope, then intersected —
this is what keeps `total`/pagination correct despite status being a
post-aggregation value.
- OpenAPI spec + FE API types are regenerated (scalar → array); no
hand-written FE.
## Summary
- Saved views now persist a versioned, typed spec (`schemaVersion` +
`spec{compositeQuery, selectedFields, display}`) instead of a bare
composite-query blob plus an opaque, frontend-owned `extraData` string
-- mirroring the pattern dashboards already use for their v2/perses
schema.
- `/api/v1/explorer/views` keeps working exactly as before: a thin
conversion layer translates to/from the legacy wire format, including
folding `extraData`'s ad hoc JSON into the typed spec and back for
backward compatibility.
- A one-time migration rewrites existing rows into the new shape and
drops the now-unused `extra_data`/`category`/`tags` columns.
### Scaffolding decisions
- Using v2 for new handlers instead of renaming old handlers to
something else for these reasons - keep the diff minimum for easier
reviews, avoiding any git history or last updated at change in old route
registration.
- Keeping the conversion to old saved view type in handler itself rather
than `savedviewtypes` package to keep it un-exported and not let them be
available anywhere else to be used. It also enables `savedviewtypes` to
be independent on query-service models.
- Modified the existing handler and it's interface to include the v2
methods instead of adding another handlerV2 since apiserver already had
handler wired in, so don't want to pass on 2 version simultaneously.
### Breaking change
- Any unknown key in the `ExtraData` will be rejected and dropped
silently in the old APIs and give error in new version.
- If there was any way to add tag or category in saved view earlier,
that data will be lost.
- Old APIs will not support the old QB request payload, only v5 format
is supported.
---
ClosesSigNoz/engineering-pod#4651
Alternative discarded https://github.com/SigNoz/signoz/pull/12208
---------
Co-authored-by: Claude Sonnet 5 <noreply@anthropic.com>
* feat: enable FGA for dashboards and their public config
* test: add integration test for dashboard FGA
* fix: fix permissions for public dashboards, pinning, views
* fix: allow viewers to manage views
* fix: remove edits to the public dashboard line
* chore: add api to retry migration for a dashboard
* feat(dashboard): add retry migration action for legacy dashboards
The legacy-dashboard dialog only offered the dashboard ID and a link to
support. Now that the v1->v2 migration can be re-run on demand, let an
editor trigger it from there and fall back to support only if it still
fails.
Retrying needs edit access (the endpoint is EDITOR-gated), so viewers
keep the ID-and-support dialog unchanged.
---------
Co-authored-by: Ashwin Bhatkal <ashwin96@gmail.com>
* fix(ruletypes): expose above_or_equal and below_or_equal in CompareOperator enum
The operators are accepted by Validate(), normalized, evaluated and
returned by the rules API, but were commented out of Enum(), so the
generated OpenAPI spec (and clients generated from it, e.g.
terraform-provider-signoz) rejected rules the server itself creates.
* fix(alerts): support above_or_equal and below_or_equal operators in CreateAlertV2
Adds the two inclusive operators to the v2 alert form: selectable in the
threshold operator dropdown, normalized from all backend aliases
(5/6, above_or_eq/below_or_eq, >=/<=), rendered with their symbols in
threshold rows and match-type tooltips, and prefilled losslessly from
dashboard panel thresholds instead of collapsing onto the strict
variants. The v1 form is left untouched.
* feat: adding gcp memorystore redis service
* refactor: updating dashboard title
* refactor: extending width of uptime gauge panel
* refactor: updating cpu utilization panel
* refactor: updating dashboard panel to use rate function instead of hack
* feat: adding compute engine service
* refactor: updating dashboard panels to use rate aggregation
* fix: correct typo and unit in compute engine dashboard
* refactor: migrating dashboard to v6
* feat(rulestatehistory): populate related logs/traces links in v2 history APIs
The v2 rule history timeline dropped the relatedLogsLink/relatedTracesLink
that v1 (getRuleStateHistory) returned per entry, which the alert history
page uses to jump from a state change to the explorer with the rule's
filter and the entry's labels. Load the rule from the rule store in the
module and build the links with contextlinks, scoped to the entry's
evaluation window like v1.
Extract the builder-query filter/group-by selection that the v1 handler
and threshold rule notifications each inlined into
contextlinks.BuilderQueryForSignal and reuse it from both the module and
ThresholdRule.
Also populate the links for top contributors, which both v1 (since #10760)
and v2 returned as always-empty fields even though the UI renders them;
contributor links span the queried range since the counts aggregate it.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
* chore(contextlinks): remove unused v3 link helpers
PrepareLinksToTraces, PrepareLinksToLogs and PrepareFilters lost their
last callers when the deprecated v3/v4 rule support was removed in #10760;
the v5 equivalents (PrepareParamsFor*V5 and PrepareFilterExpression) are
what all remaining callers use.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
* chore: end doc comments with a period to satisfy godot
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
* test(alerts): cover v2 rule history related links for logs and traces
Each test fires a rule with a filter and a service.name group-by, then
asserts the recorded firing entry and top contributor carry a related
explorer link for the rule's signal only, with the label-rewritten filter
expression, the evaluation window on timeline entries and the queried
range on contributors.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
* feat(contextlinks): shrink explorer links to the minimal payload
The explorer pages read only the data source and filter expression from a
shared link and fill in the rest of the query shape with defaults, so stop
shipping the v3 builder-query ceremony (queryName, aggregateOperator,
aggregateAttribute, stepInterval, paging fields) and the timeRange and
options params nothing reads. Links shrink from ~1.2k to ~450 chars and
contextlinks no longer depends on the v3 model.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
* fix(rulestatehistory): derive link windows from the evaluation envelope
Rules created through the current UI store the window in the v2alpha1
evaluation envelope with no top-level evalWindow, so the previous 5m
fallback produced wrong link windows for any non-default rolling window
and could not represent cumulative windows at all. Use the envelope's
NextWindowFor like the rule engine does, keeping the top-level
evalWindow (default 5m) as the fallback for rules without an envelope.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
* chore(contextlinks): simplify double-encoding comment
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
* test(alerts): use literal matchType/op in fixtures and drop link unit tests
Replace the numeric matchType/op codes in all alert scenario fixtures
with their literal forms (at_least_once, above, ...) which the API
normalizes to the same canonical values, and remove the rule history
link unit tests since the integration tests cover the behavior
end-to-end.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
* test(alerts): move rule history helpers into the shared alerts fixtures
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
---------
Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
* chore: fix schema based on migration errors
* test: add rejection based integration tests for new validations
* fix: remove datasource field from schema
* fix: remove requirement for links to be always present
* fix: make links use defined type
* test: add integration test for link omission roundtrip
* test: change not in to None for links in panel
---------
Co-authored-by: Ashwin Bhatkal <ashwin96@gmail.com>
* fix(dashboards-v2): make panel/dashboard links required and non-nullable
* fix: validate links on read from db as well
* fix: allow all as value for signal
* fix: dont allow empty string for signal
* fix(dashboards-v2): dedicated `all` dynamic-variable signal (frontend + client)
* test: add empty links to new payloads in integration tests
---------
Co-authored-by: Naman Verma <naman.verma@signoz.io>
* feat: adding gcp memorystore redis service
* refactor: updating dashboard title
* refactor: extending width of uptime gauge panel
* refactor: updating cpu utilization panel
* refactor: updating dashboard panel to use rate function instead of hack
* fix(querybuildertypesv5): omit unset stepInterval on the wire
Step is a struct (struct{ time.Duration }), so omitempty had no effect — an
unset stepInterval serialized as 0 instead of being omitted, so a typed
client reading a query back saw a 0 it never sent (create -> GET drift).
Tag stepInterval with ,omitzero so an unset value is dropped while a set
value still serializes (as seconds), on all three sites: builder query,
trace-operator, and secondary aggregation. Schema-invisible (no OpenAPI /
client change). source and the metric enums were already handled in #12164.
* fix(telemetrytypes): round-trip empty fieldContext/fieldDataType on field keys
A TelemetryFieldKey can deliberately leave fieldContext/fieldDataType empty
to match across any context / data type, but ,omitzero dropped that empty
value on serialize, so a typed client that sent "" read it back as absent
(create -> GET drift).
Make both fields always serialize and add the empty member to their Enum()s
so "" is a valid schema value that round-trips verbatim — the same approach
#12164 used for source. Signal keeps ,omitzero: its empty value is invalid
for the query/variable signal contexts that share the enum (adding "" there
breaks those consumers), and a field key's signal is not deliberately empty.
Regenerate the OpenAPI spec + client (fieldContext/fieldDataType enums gain
"") and update the ScalarData marshal test (column keys now echo the fields).
* fix(telemetrytypes): round-trip empty signal on field keys
Extend the field-key round-trip fix to Signal: add the empty member to
Signal.Enum() and make TelemetryFieldKey.Signal always serialize, so an
empty ("any") field-key signal round-trips as a valid value instead of
being dropped — matching the fieldContext/fieldDataType treatment.
The Signal enum is shared with query/variable signals, where "" is invalid.
Narrow the frontend's TelemetrySignal type to logs/traces/metrics (so the
variable/panel signal selectors stay exhaustive), label the empty member in
the panel type switcher's map, and fold an empty drilldown signal into "all".
Regenerate the OpenAPI spec + client (Signal enum gains ""), and update the
ScalarData marshal test and the querierlogs aggregation label assertions to
include the now-serialized empty signal.
* fix(dashboardtypes): round-trip zero-valued variable/display fields
omitempty dropped explicit zero values from the create -> GET response, so
a typed client (Terraform/SDK) that sent them read back null and reported
drift. Remove the tag so these always serialize:
- Display.Description ("" round-trips; applies to dashboard/panel/variable
displays)
- TextVariableSpec.Constant (constant: false, like the disabled fix)
- ListVariableSpec.CustomAllValue / CapturingRegexp ("" round-trips)
Scalars carry no nullability, so the OpenAPI spec and generated client are
unchanged. Sort stays omitzero: its "no sort" value is "none", not "", so
omitzero only omits the invalid unset state.
* fix(dashboardtypes): round-trip panel and dashboard links
`links` used omitempty (dropped an explicit []) and its element type was the
imported perses dashboard.Link, whose own fields tag name/tooltip/
renderVariables/targetBlank omitempty — so a link's false/"" were dropped
too, and a typed client read them back as null.
- Replicate dashboard.Link as a SigNoz Link type (same pattern as
ListVariableSpec/TextVariableSpec) with every field always serialized.
- Use ,omitzero on PanelSpec.Links and DashboardSpec.Links so an explicit
[] round-trips while an unset list stays omitted (never null).
Regenerate the OpenAPI spec and frontend client: the element schema is now
DashboardtypesLink (was the perses DashboardLink) and links is nullable.
Update the frontend consumers to the renamed type and coalesce the now
type-nullable spec.links (never null on the wire) at its two boundaries.
* test(dashboard): cover variable/display/link round-trip cases
Extend the v2 dashboard round-trip test with the spec-wide zero values this
PR fixes: a display description "", a text variable's constant false, a list
variable's customAllValue/capturingRegexp "", an explicit [] of panel links
that round-trips, a link whose own zero-valued fields (name/tooltip "",
renderVariables/targetBlank false) echo back, and a linkless panel whose
links stay omitted (never null).
* test(dashboard): accept null-or-absent for unset panel links
A panel with no links round-trips as "links": null rather than being
omitted (the panel serialization path differs from the query slices, which
omit). Both mean "no links" and neither drifts for a typed client, so assert
the value is None (null or absent) instead of strictly absent. The explicit
[] case still asserts a verbatim round-trip, which is the guarantee the fix
provides.
* fix(dashboardtypes): round-trip remaining zero-valued spec fields
Complete the dashboards-v2 create -> GET round-trip audit:
- DashboardSpec.Datasources: ,omitempty -> ,omitzero so an explicit {}
round-trips (omitempty dropped it) while an unset map stays omitted.
- DashboardV2 Image, DashboardSpec.Duration/RefreshInterval: drop ,omitempty
so an explicit "" round-trips (same class as Display.Description). The
server accepts "": DurationString.validate() returns nil for len 0, and
Image/Duration/RefreshInterval have no create-time validation, so a
GET-then-PUT of "" is not rejected.
Scalars carry no nullability (no spec change); the datasources map is now
nullable: true in the regenerated OpenAPI spec and client.
* test(dashboard): cover datasources/image/duration/refreshInterval round-trip
Extend the round-trip test with the spec-wide zero values just fixed: a
dashboard-level image "", spec duration/refreshInterval "", and an explicit
empty datasources {} that must echo back as {} (omitzero) rather than being
dropped.
* fix(querybuildertypesv5): omit unset metric enum fields on the wire
A metric builder query serialized empty strings for its enum fields
because omitempty has no effect on struct-backed valuer types:
"source":"", "aggregations":[{"temporality":"","timeAggregation":"","spaceAggregation":""}]
Those "" values are not members of the corresponding OpenAPI enums
(source=[meter], temporality=[delta,cumulative,unspecified], etc.), so a
typed client reading a rule back rejected it (create -> GET round-trip
drift; terraform-provider-signoz generate-config failed schema validation).
Tag Source/Temporality/TimeAggregation/SpaceAggregation with ,omitzero so
an unset value is dropped instead of emitted as an invalid "", matching the
existing convention (dashboardtypes Sort, telemetrytypes field keys). Valid
values still serialize. The OpenAPI spec regenerates byte-identical, which
confirms the enums were already correct.
* test(querybuildertypesv5): cover client-sent empty enum values
A client (e.g. terraform) may send explicit source:"" / temporality:"" for
an unset enum. Assert unmarshaling accepts them, normalizes to the zero
value, and re-marshaling drops them so the round-trip never echoes an
invalid "" back.
* fix(querybuildertypesv5): allow empty metric enum values in the spec
The server accepts and echoes back an unset source, temporality, and
timeAggregation for a metric query (a create -> GET returns "" for them), but
their OpenAPI enums omitted "". A typed client (terraform-provider-signoz
generate-config) therefore rejected the config generated for an imported rule.
Add "" as a valid member of the Source, Temporality, and TimeAggregation enums
so the spec matches what the server actually accepts and returns. spaceAggregation
is left unchanged: an empty value is rejected with 400 at creation (IsValid), so
it is never stored or echoed and "" must stay out of its enum.
Drop the earlier ,omitzero tags: these fields already always-serialize, so an
accepted "" round-trips faithfully instead of being silently dropped (silent
mutation is itself drift). source loses its no-op omitempty for the same reason.
Regenerate the OpenAPI spec and frontend client (both git-diff gated).
* test(querybuildertypesv5): assert accepted empty enums round-trip
Empty source/temporality/timeAggregation are echoed back (not dropped) and are
stable across marshal -> unmarshal -> marshal; spaceAggregation carries a valid
value since an empty one is 400'd at creation.
* test(querybuildertypesv5): merge and rename metric enum round-trip test
Fold the unmarshal-echo case into the table-driven marshal round-trip test
(its marshal -> unmarshal -> marshal check already covers the client-sends-""
path) and rename to TestQueryBuilderQuery_MetricAggregation_MarshalJSONEnumRoundTrip.
* style(metrictypes): drop explanatory comments on enum changes
Remove the comments added to Temporality/TimeAggregation Enum() and the metric
enum round-trip test case.
* style(telemetrytypes): drop explanatory comment on Source enum change
Remove the comment added to Source.Enum(), keeping the pre-existing doc/TODO.
* fix(dashboardtypes): accept threshold value of 0 on create
A NumberPanel/TimeSeries/Table threshold with `value: 0` (a legitimate
value the SigNoz UI emits by default) was rejected on create with
`dashboard_invalid_input` "Field validation for 'Value' failed on the
'required' tag".
go-playground/validator's `required` treats a numeric field equal to its
zero value as "missing", so `validate:"required"` on the float `Value`
wrongly rejected 0. Drop `validate:"required"` from `Value` on
ThresholdWithLabel and ComparisonThreshold; keep `required:"true"` since
the field is always present in the schema (0 is a valid present value, not
an absent one), so the OpenAPI/generated client are unaffected. `Color`
keeps both tags — an empty colour is genuinely invalid.
Drop the two "missing value" cases from TestValidateRequiredFields, which
asserted the removed invariant.
* fix(querybuildertypesv5): round-trip zero-valued query spec fields
A dashboard/alert query that sets a zero-valued field — `disabled: false`,
`legend: ""`, or an explicit empty `groupBy`/`order`/`selectFields`/etc. —
created fine but the GET response omitted it, so a typed client that echoes
what it sent (Terraform, SDKs, PUT-after-GET) read back `null`/absent and
reported drift. `,omitempty` dropped these zero values on the way out.
Fix the create -> GET asymmetry:
- Slice fields use `,omitzero` instead of `,omitempty`. `omitzero` omits a
nil slice (field never set stays absent) but keeps an explicit non-nil
`[]`, so an empty array round-trips as `[]` and there is no `null`
regression. Applied to groupBy, order, selectFields, aggregations,
functions, secondaryAggregations and function args across the builder,
formula, trace-operator and join specs, plus ListPanelSpec.selectFields.
- Scalars `disabled` (bool) and `legend` (string) drop the tag entirely;
`omitzero`/`omitempty` both suppress false/"", so the only way to
round-trip them is to always serialize.
Result types in resp.go keep `,omitempty` — they are server-computed and
never round-tripped. Regenerate docs/api/openapi.yml and the frontend
client: the omitzero slices are now `nullable: true` in the schema (never
null on the wire, but the generated types gain `| null`, which existing
consumers already handle via `?? []`).
* test(dashboard): round-trip serialization for zero-valued fields
Add a v2 dashboards integration test that creates one minimal dashboard
(stripped from SigNoz/dashboards cicd-perses.json) and asserts the
create -> GET round-trip preserves every zero-valued field the fix targets:
- threshold value 0 (ComparisonThreshold + ThresholdWithLabel) is accepted
on create and echoed back
- builder slices set to an explicit [] (groupBy/order/selectFields/functions)
round-trip as [], while a bare builder's unset slices stay absent (never
null) on read
- scalars disabled/legend always echo false/""
Table-driven: one equality table for round-tripped values and one absence
table for omitted slices.
* test(dashboard): fold round-trip test into 03_v2_dashboard
Move test_dashboard_v2_roundtrip_preserves_zero_values alongside the other
v2 dashboard tests (test_create_rejects_*, lifecycle, ...) instead of a
standalone file, with the dashboard payload inlined per this suite's style.
* feat(authz): enable FGA for telemetry resources on v5 query_range
Authorize /api/v5/query_range and /preview at the telemetry-resource level,
derived from the request body:
- coretypes: ResourceWithID + ResourceExtractor as the resource-level analogue
of the id extractors; NewResolvedResourceWithID/NewResolvedResourceWithError;
telemetryresource selector regex widened to query-type selectors with up to
two hashed segments (metric name, where clause) or wildcards
- telemetrytypes: QueryRangeResources maps each query to its telemetry
resource (signal/source aware: audit-logs, meter-metrics) with a hierarchical
selector id (query_type/<hash(metric)>/<hash(where)>); PrefixSelector expands
the id into the grant ladder [exact, prefix/*..., *]
- handler: generic TelemetryResourceDef fans out an injected ResourceExtractor;
fails closed when extraction errors or resolves nothing
- audit: log and skip resolved resources that carry a resolution error
- querier routes: ViewAccess -> CheckResources with telemetry read scopes;
substitute_vars stays ViewAccess (no telemetry access)
- sqlmigration 099: backfill telemetry read tuples for existing orgs
(admin: logs/traces/metrics/audit-logs/meter-metrics; editor/viewer:
logs/traces/metrics)
* feat(authz): widen telemetry selector segments to 128 bits
64-bit truncation permits chosen-collision attacks at ~2^32 work; 128 bits
pushes this to 2^64. No hashed selector is persisted yet, so the change is
free.
* chore(docs): regenerate openapi spec with telemetry read scopes
* feat(telemetry): add where clause visitor
* refactor(telemetry): restructure normalizer file and quote bare values
* feat(authz): gate v5 query_range on service.name telemetry selectors
* feat(authz): encode telemetry grants as query-type qualified atom selectors
* feat(authz): move telemetry grant key to plaintext selector segment
* feat(authz): use escaped plaintext telemetry selectors with mechanical ladder
* revert(authz): restore transaction group diff in role update
* test(authz): add querierauthz integration suite for telemetry query_range gating
* test(authz): seed logs so service.name resolves in allowed querierauthz cases
* feat(authz): backfill telemetry read tuples for existing orgs
* chore(authz): reword empty composite query error message
* feat(authz): add meter metrics and audit logs to clickhouse sql
* Revert "feat(authz): add meter metrics and audit logs to clickhouse sql"
This reverts commit c9d870e0ee.
* feat(authz): grant meter-metrics to editor/viewer, keep clickhouse admin-only
* feat(authz): remove the audit logs from clickhouse check altogether until it's introduced
* fix(ruletypes): always serialize notificationSettings.usePolicy
usePolicy is a plain bool tagged omitempty, so a false value is dropped
from the GET response. Clients that pin usePolicy to false read it back as
absent/null. Drop omitempty (matching Renotify.Enabled) so false always
serializes and round-trips.
* test(ruletypes): assert usePolicy round-trips in minimal read shape
usePolicy now always serializes, so the minimal read shape includes it with a false value rather than omitting it.
* fix(ruletypes): always serialize notificationSettings.groupBy
Like usePolicy, groupBy dropped its omitempty so an explicitly-set empty value round-trips instead of reading back as absent. A nil groupBy now serializes as null.
* fix(ruletypes): use omitzero for notificationSettings.groupBy
omitzero omits groupBy only when nil (unset) while preserving an explicitly-set empty array as [], so unset and empty stay distinguishable instead of every response carrying groupBy: null. Matches the sibling newGroupEvalDelay tag.
* fix(ruletypes): use omitzero for renotify.alertStates
Symmetric to groupBy: omitzero omits alertStates only when nil (unset renotify configs stay absent, no regression) while echoing an explicitly-set empty array as [].
* chore(ruletypes): regenerate openapi spec and api client
groupBy and renotify.alertStates switched to omitzero, so the generated spec marks both slices nullable and the orval client types them as [] | null.
* fix: set correct opapi response model for span mapper list
* fix: change group_id to groupId in response
* fix: format properly
* fix: update fixtures
* chore: added types and open api spec changes
* chore: added method to calculate reason
* chore: per group pod status counts with req metric checks method added
* chore: wired up pod status counts
* chore: pod restarts type added
* chore: added restart counts for the group
* chore: bug in query fix
* chore: onboarding API changes
* chore: integration tests added
* chore: added podcountsbyphase in other entities
* chore: added pod status counts for other entities
* chore: added integration tests for other entities
* chore: added checks api changes for other entities
* chore: rearrangement
* chore: removed succeeded status and mark it as completed
* chore: query beautified
* chore: corrected metrics list for metadata lookup
* chore: removed dead constants
* chore: goroutines for ListHosts
* chore: goroutines for ListPods
* chore: goroutines for ListNodes
* chore: goroutines for ListNamespaces
* chore: goroutines for ListClusters
* chore: goroutines for ListDeployments
* chore: goroutines for ListStatefulsets
* chore: added goroutines for ListStatefulsets, ListJobs and ListDaemonsets
* chore: added function
* chore: added struct changes
* chore: added count attr keys
* chore: wired counts to the response fields
* chore: regenerated API spec
* chore: merged main, resolved conflicts
* chore: nodes count surfacing
* chore: integration tests added
* fix: use tuple mapping to uniquely identify attrs:
* chore: integration tests update