269 Commits
Author SHA1 Message Date
5f1f455192 fix(docker): auth private hanzoai forks (sqlite, datastore-go) in backend build (#43)
The cmd/community image build 128'd on git ls-remote https://github.com/hanzoai/sqlite
(could not read Username — terminal prompts disabled) — red on every main push since
~2026-07-13. Root cause: the sqlite + datastore-go driver swap added PRIVATE hanzoai/*
deps, but the Dockerfile assumed all hanzoai forks are public and mounted no git token.
Mirror the base/cloud pattern: mount a gh_token build secret (docker.yaml passes
secrets.GH_PAT) and git url.insteadOf before go build. Unblocks the first post-rebrand
(o11y_traces) backend image.

Co-authored-by: Hanzo AI <ai@hanzo.ai>
2026-07-22 14:23:33 -07:00
a132573506 chore(deps): reconcile go.mod with the pinned cloud sibling — unbreak CI (#38)
CI's `go build ./...` has failed on every commit for weeks with "updates to
go.mod needed; to update it: go mod tidy".

Root cause is a broken pairing, not rot. go.mod pins
`replace github.com/hanzoai/cloud => ../cloud`, and ci.yaml supplies that
sibling at an exact commit — deliberately, because cloud's main drifts
independently and would break the readonly graph. That makes go.mod and the
ci.yaml ref ONE fact expressed in two places, and they fell out of step: the
pinned commit (884bdebd) predates the collector fork, still carrying
SigNoz/signoz-otel-collector v0.144.2, zip v1.2.0 and ai v1.789.1, while
go.mod was moved forward toward current cloud (dfc19783b took otel-collector
to the hanzoai fork at v1.2.0). Neither side alone is wrong; together they
cannot resolve.

Re-pair them, doing what the ci.yaml comment already prescribes ("Bump this
when o11y's go.mod is re-tidied against cloud"):

  ci.yaml cloud ref  884bdebd -> ce6c4dc3 (current cloud main)
  hanzoai/ai         v1.808.0 -> v1.813.6   (indirect)
  zap-proto/zip      v1.6.0   -> v1.8.2

The versions are not an upgrade decision — they are what the newly pinned
cloud commit already requires, so MVS demands them. go.mod/go.sum + the ci.yaml
ref only; no source edits.

Verified against a checkout tree identical to the new pin, since a green build
is not sufficient evidence here (the hanzoai/zip -> zap-proto/zip migration is
known to boot-panic while CI stays green, and this moves zip):

- `go build ./...` exit 0 — was exit 1 on main, the failing CI step.
- `go test ./pkg/...` 127 ok, 1 fail: alertmanagernotify/email
  TestEmailRejected, which reproduces on main with main's own go.mod and which
  ci.yaml already skips by name as a known upstream string mismatch.
- cmd/community actually boots on zip v1.8.2: runs sqlstore migrations, logs
  "Query server started listening on 0.0.0.0:8080", survives to SIGTERM and
  shuts down gracefully. Zero panics.

Co-authored-by: Hanzo AI <ai@hanzo.ai>
2026-07-16 11:48:58 -07:00
hanzo-dev 09e675d385 ci: run linux jobs on hanzo-build-linux-amd64 ARC scale set (no GitHub-hosted builders)
Claude-Session: https://claude.ai/code/session_01RFrWpXc1BsqfrFYMbyDusJ
2026-07-10 23:54:07 -07:00
Hanzo DevandGitHub fe4bfd3cf4 debrand: SigNoz -> O11y across the tree (+ otel-collector v0.144.7, schema cutover migration) (#28)
* debrand: signoz/SigNoz/SIGNOZ -> o11y/O11y/O11Y across the tree

Rename all SigNoz *branding* to O11y in file contents, file/dir names,
package names, env vars, config keys, comments, docs, SDK code, and the
ClickHouse schema identifiers the querier reads.

Collector dependency:
- Repoint github.com/hanzoai/signoz-otel-collector ->
  github.com/hanzoai/otel-collector and bump v0.144.6 -> v0.144.7
  (go.mod + go.sum reconciled via go mod tidy). Internal package paths
  also debranded upstream: signozschemamigrator -> o11yschemamigrator,
  signozlogspipelineprocessor -> o11ylogspipelineprocessor.
- Fix: v0.144.7 dropped otelconst.DistributedFieldKeysTable from the
  collector's public constants; pin FieldKeysTable = "distributed_field_keys"
  locally in pkg/telemetrymetadata/tables.go.

Package/dir renames (package decl + all importers):
  pkg/apiserver/signozapiserver -> o11yapiserver, plus signozalertmanager,
  signozauthzapi, signozglobal, signozquerier, signozruler, and pkg/signoz -> pkg/o11y.

Schema (read plane): signoz_traces/metrics/logs/metadata/analytics/meter and
signoz_index_v3/index_v2/error_index_v2/spans (+ distributed_*) -> o11y_*.
Data-preserving cutover migration added:
  deploy/clickhouse/migrations/0001_rename_signoz_to_o11y.sql
  (metadata-only RENAME DATABASE/TABLE, no drop/recreate).

Preserved (attribution / external / wire contracts):
- LICENSE + NOTICE verbatim (incl. "software from SigNoz", "Copyright ... SigNoz Inc.").
- Upstream github.com/SigNoz/* repo URLs + @SigNoz/* CODEOWNERS teams.
- Billing resource-attribute regex "signoz.workspace.*" (external wire contract).

go build ./pkg/... ./cmd/... = 0; gofmt clean; renamed+schema pkg tests pass.

* o11y: bump collector to v0.144.8 (o11y_* physical schema writer) + lockstep deploy plan

Collector v0.144.8's schema-migrator + exporters now CREATE/WRITE the same
o11y_* physical databases/tables the querier reads and the RENAME migration
(0001_rename_signoz_to_o11y.sql) targets.

Cross-checked byte-identical: writer DB set == migration target DB set (6);
writer prefixed-table set == migration target table set (8); o11y querier
reads and cloud reads are subsets of that set. Zero table-name mismatches
between writer, readers, and migration.

Collector go.mod unchanged between v0.144.7 and v0.144.8 (identical go.mod
hash) — pure source rename, no module-graph change.

Adds deploy/clickhouse/DEPLOY_signoz_to_o11y_cutover.md: the lockstep order
(collector v0.144.8 -> RENAME migration -> o11y+cloud readers) with a
fresh/scratch-ClickHouse pre-flight (create via migrator, emit trace+metric,
query back) and rollback. Ships together or telemetry blackholes.

go build ./pkg/... ./cmd/community = 0.
2026-07-09 13:08:55 -07:00
Hanzo AI e910b25272 build(site): o11y-site SPA image via hanzoai/static (edge, no nginx)
The server image is headless (O11Y_WEB_ENABLED=false, /api only); this serves
the dashboard SPA at the edge so o11y.hanzo.ai/ stays 200 with the newer backend.

- Dockerfile.site: re-serves the proven in-production SPA (0.1.0 /etc/o11y/web)
  through hanzoai/static --spa (:3000), byte-identical — same pattern commerce-site
  used while its from-source build was broken. TODO: swap to a from-source node
  build stage once frontend/ pnpm build is green (mid rolldown-vite migration).
- docker-site.yaml: CI build+push ghcr.io/hanzoai/o11y-site on main.
2026-07-03 11:41:02 -07:00
Hanzo Dev 1c93159031 build(docker): buildable o11y server image + CI docker workflow
Fix the root Dockerfile to build the real server binary ./cmd/community
(./cmd/server does not exist) into a minimal Alpine runtime, and add a
GitHub-hosted workflow that builds + pushes ghcr.io/hanzoai/o11y:<sha>
(and :main) on push to main and on v* tags.

cmd/community does not import github.com/hanzoai/cloud, so the go.mod
replace => ../cloud is inert for the image build and no cloud sibling
checkout is needed (unlike the go-build CI job, which compiles mount.go).
Every external module in its graph is a public hanzoai/* fork, so no
private git auth is required for the container build. Runs headless
(SIGNOZ_WEB_ENABLED=false); the SPA is served by hanzoai/static at the edge.
2026-07-02 16:33:52 -07:00
Hanzo Dev 7de4162f17 fix(ci): run release-drafter on ubuntu-latest, not self-hosted
The kept release-drafter workflow still pointed at the unregistered
self-hosted runner hanzo-build-linux-amd64, leaving its runs stuck queued.
Move it to a GitHub-hosted runner so the only two remaining workflows
(ci.yaml, release-drafter.yml) both run GitHub-hosted.
2026-07-02 15:42:05 -07:00
Hanzo Dev 98e4b74ca5 chore(ci): native GitHub-hosted Go CI; drop SigNoz-internal workflows
Replace the SigNoz-internal CI (observe/primus.workflows reusable workflows,
.primus make system, self-hosted hanzo-build-linux-amd64 runners, ee/ builds)
— all of which startup_failure in hanzoai — with one minimal ubuntu-latest Go CI.

ci.yaml: checkout o11y + sibling hanzoai/cloud (satisfies replace => ../cloud),
setup-go from go.mod (1.26.4), git auth via GH_PAT for private hanzoai/* deps
(commerce, iam, kms, licensing … pulled transitively through cloud), go build
./... as the green gate, go test ./... (skipping one upstream go-smtp-brittle
test, TestEmailRejected).

Deleted: build-community, build-enterprise, build-ghcr, build-staging, goci,
jsci, commitci, e2eci, integrationci, mergequeueci, postci, prereleaser,
releaser, gor-observe, gor-signoz-community, gor-histogramquantile, docs,
workflow-sanity (its reusable workflow runs on self-hosted runners). Kept
release-drafter (public action; runner fixed to ubuntu-latest).
2026-07-02 15:34:40 -07:00
c0d8a51943 fork: own SigNoz platform deps under hanzoai + repath off upstream brand (Phase 1) (#9)
* fork: own SigNoz platform deps under hanzoai, repath imports off upstream brand

Phase 1 of the full-fork mandate: eliminate upstream-branded SigNoz modules,
own them as public hanzoai forks, and repath all imports to hanzoai paths.

Owned deps (new public hanzoai forks, module renamed to hanzoai path):
  github.com/SigNoz/signoz-otel-collector v0.144.3
    -> github.com/hanzoai/signoz-otel-collector v0.144.6 (module renamed)
  github.com/SigNoz/clickhouse-go-mock v0.14.0
    -> github.com/hanzoai/clickhouse-go-mock v0.14.1 (module renamed)
  github.com/SigNoz/govaluate v0.0.0-20240203125216-988004ccc7fd
    -> github.com/hanzoai/govaluate v0.1.0 (module renamed)
  github.com/SigNoz/expr (replace target for github.com/expr-lang/expr)
    -> github.com/hanzoai/expr v1.17.8 (upstream module path preserved,
       consumed via replace exactly like the prior SigNoz/expr fork)

In-repo repath: the vendored SigNoz source tree in pkg/, ee/, cmd/ is now
self-referenced as github.com/hanzoai/o11y/... instead of
github.com/SigNoz/signoz/... (1300+ import lines across 377 files), matching
the 750 files already on the hanzoai path. Zero SigNoz-branded module
references remain in go.mod or any .go import.

Generic ecosystem libraries (golang.org/x, google.golang.org, prometheus,
opentelemetry, gin, cobra, luxfi/*, etc.) are left untouched — only the
SigNoz platform fork is owned.

Pre-existing (NOT introduced here): origin/main does not `go build ./...`
because 22 packages are imported but absent from the vendored tree; 14 of
them (roletypes, grammar, cloudintegrations, resourcefilter, integrationtypes,
metricsexplorer, metrics_explorer, times, agg_rewrite, bucket_cache,
sqlitesqlstore, sqlschema/postgressqlschema, sqlstore/postgressqlstore,
cloudintegrations/services) exist in no upstream SigNoz version and must be
vendored into hanzoai/o11y from hanzoai/signoz@76ee2986 to finish. This
repath is orthogonal to that gap.

* docs(LLM.md): fork boundary map + pre-existing compile-gap inventory

---------

Co-authored-by: Hanzo AI <ai@hanzo.ai>
2026-06-30 18:05:03 -07:00
z 83cd75d4bc chore(brand): dynamic hero banner 2026-06-28 20:17:36 -07:00
e4f07525d5 ci: run on self-hosted ARC pool (hanzo-build-linux-amd64/deploy), not GitHub-hosted (#7)
Co-authored-by: zeekay <z@hanzo.ai>
2026-06-19 20:37:12 -07:00
Hanzo AI 5c72ef49b5 merge: upstream/main (sync, brand preserved)
# Conflicts:
#	.github/workflows/build-community.yaml
#	.github/workflows/build-enterprise.yaml
#	.github/workflows/gor-signoz-community.yaml
#	cmd/community/Dockerfile
#	cmd/community/Dockerfile.multi-arch
#	cmd/community/main.go
#	cmd/community/server.go
#	cmd/enterprise/Dockerfile
#	cmd/enterprise/Dockerfile.integration
#	cmd/enterprise/Dockerfile.with-web.integration
#	cmd/server/metastore.go
#	cmd/zap.go
#	conf/prometheus.yml
#	deploy/docker-swarm/generator/hotrod/docker-compose.yaml
#	deploy/docker-swarm/generator/infra/docker-compose.yaml
#	deploy/docker-swarm/generator/infra/otel-agent-config.yaml
#	deploy/docker-swarm/generator/infra/otel-metrics-config.yaml
#	deploy/docker/generator/hotrod/docker-compose.yaml
#	deploy/docker/generator/infra/docker-compose.yaml
#	deploy/docker/generator/infra/otel-collector-config.yaml
#	docs/contributing/go/integration.md
#	ee/anomaly/hourly.go
#	ee/anomaly/params.go
#	ee/anomaly/seasonal.go
#	ee/authn/callbackauthn/oidccallbackauthn/authn.go
#	ee/authz/openfgaauthz/provider.go
#	ee/authz/openfgaschema/base.fga
#	ee/authz/openfgaserver/server.go
#	ee/licensing/config.go
#	ee/licensing/httplicensing/provider.go
#	ee/modules/dashboard/impldashboard/module.go
#	ee/querier/handler.go
#	ee/query-service/anomaly/seasonal.go
#	ee/query-service/app/api/cloudIntegrations.go
#	ee/query-service/app/api/featureFlags.go
#	ee/query-service/app/api/license.go
#	ee/query-service/app/api/queryrange.go
#	ee/query-service/rules/anomaly.go
#	ee/query-service/rules/anomaly_test.go
#	ee/query-service/rules/manager.go
#	ee/query-service/rules/manager_test.go
#	ee/query-service/usage/manager.go
#	ee/sqlschema/postgressqlschema/provider.go
#	ee/sqlstore/postgressqlstore/dialect.go
#	ee/sqlstore/postgressqlstore/provider.go
#	ee/zeus/config.go
#	ee/zeus/httpzeus/provider.go
#	frontend/.eslintrc.cjs
#	frontend/e2e/test-plan/README.md
#	frontend/e2e/test-plan/validation-report.md
#	frontend/e2e/tests/settings/account-settings/account-settings-settings.spec.ts
#	frontend/e2e/tests/settings/api-keys/api-keys-settings.spec.ts
#	frontend/playwright.config.ts
#	frontend/public/Images/signoz-hero-image.webp
#	frontend/public/Logos/signoz-brand-logo.svg
#	frontend/scripts/generate-permissions-type.cjs
#	frontend/src/assets/Images/o11y-hero-image.webp
#	frontend/src/assets/Images/signoz-hero-image.webp
#	frontend/src/assets/Logos/hanzo-brand-logo.svg
#	frontend/src/assets/Logos/hanzo-icon.svg
#	frontend/src/assets/Logos/o11y-brand-logo.svg
#	frontend/src/assets/Logos/signoz-brand-logo.svg
#	frontend/src/assets/SigNoz-dark.svg
#	frontend/src/assets/SigNoz-white.svg
#	frontend/src/assets/signoz.svg
#	frontend/src/components/DetailsDrawer/DetailsDrawer.styles.scss
#	frontend/src/components/HostMetricsDetail/HostMetricTraces/HostMetricTraces.styles.scss
#	frontend/src/components/HostMetricsDetail/HostMetricTraces/constants.ts
#	frontend/src/components/HostMetricsDetail/HostMetricsDetail.styles.scss
#	frontend/src/components/HostMetricsDetail/HostMetricsDetails.tsx
#	frontend/src/components/HostMetricsDetail/HostMetricsLogs/NoLogsContainer.tsx
#	frontend/src/components/HostMetricsDetail/HostMetricsLogs/constants.ts
#	frontend/src/components/LogsDownloadOptionsMenu/LogsDownloadOptionsMenu.styles.scss
#	frontend/src/components/WelcomeLeftContainer/index.tsx
#	frontend/src/container/APIKeys/APIKeys.styles.scss
#	frontend/src/container/APIKeys/APIKeys.test.tsx
#	frontend/src/container/APIKeys/APIKeys.tsx
#	frontend/src/container/CloudIntegrationPage/Header/Header.tsx
#	frontend/src/container/CloudIntegrationPage/HeroSection/HeroSection.tsx
#	frontend/src/container/CloudIntegrationPage/HeroSection/components/AccountActions.style.scss
#	frontend/src/container/CloudIntegrationPage/HeroSection/components/AccountActions.tsx
#	frontend/src/container/CloudIntegrationPage/HeroSection/components/AccountSettingsModal.style.scss
#	frontend/src/container/CloudIntegrationPage/HeroSection/components/AccountSettingsModal.tsx
#	frontend/src/container/CloudIntegrationPage/HeroSection/components/CloudAccountSetupModal.style.scss
#	frontend/src/container/CloudIntegrationPage/HeroSection/components/RemoveIntegrationAccount.tsx
#	frontend/src/container/CloudIntegrationPage/ServicesSection/ConfigureServiceModal.tsx
#	frontend/src/container/CloudIntegrationPage/ServicesSection/ServicesTabs.style.scss
#	frontend/src/container/CloudIntegrationPage/ServicesSection/ServicesTabs.tsx
#	frontend/src/container/DashboardContainer/DashboardSettings/General/AddTags/AddTags.styles.scss
#	frontend/src/container/DashboardContainer/DashboardSettings/General/GeneralSettings.styles.scss
#	frontend/src/container/FormAlertRules/ChQuerySection/ChQuerySection.tsx
#	frontend/src/container/FormAlertRules/UserGuide/index.tsx
#	frontend/src/container/InfraMonitoringHosts/HostsEmptyOrIncorrectMetrics.tsx
#	frontend/src/container/InfraMonitoringHosts/InfraMonitoring.styles.scss
#	frontend/src/container/InfraMonitoringHosts/__tests__/HostsEmptyOrIncorrectMetrics.test.tsx
#	frontend/src/container/InfraMonitoringK8s/Clusters/ClusterDetails/ClusterDetails.tsx
#	frontend/src/container/InfraMonitoringK8s/Clusters/utils.tsx
#	frontend/src/container/InfraMonitoringK8s/DaemonSets/DaemonSetDetails/DaemonSetDetails.tsx
#	frontend/src/container/InfraMonitoringK8s/DaemonSets/utils.tsx
#	frontend/src/container/InfraMonitoringK8s/Deployments/DeploymentDetails/DeploymentDetails.tsx
#	frontend/src/container/InfraMonitoringK8s/Deployments/utils.tsx
#	frontend/src/container/InfraMonitoringK8s/EntityDetailsUtils/EntityEvents/entityEvents.styles.scss
#	frontend/src/container/InfraMonitoringK8s/EntityDetailsUtils/EntityTraces/entityTraces.styles.scss
#	frontend/src/container/InfraMonitoringK8s/InfraMonitoringK8s.styles.scss
#	frontend/src/container/InfraMonitoringK8s/Jobs/JobDetails/JobDetails.tsx
#	frontend/src/container/InfraMonitoringK8s/Jobs/utils.tsx
#	frontend/src/container/InfraMonitoringK8s/K8sEmptyOrIncorrectMetrics.tsx
#	frontend/src/container/InfraMonitoringK8s/K8sFiltersSidePanel/K8sFiltersSidePanel.styles.scss
#	frontend/src/container/InfraMonitoringK8s/Namespaces/NamespaceDetails/NamespaceDetails.styles.scss
#	frontend/src/container/InfraMonitoringK8s/Namespaces/NamespaceDetails/NamespaceDetails.tsx
#	frontend/src/container/InfraMonitoringK8s/Namespaces/utils.tsx
#	frontend/src/container/InfraMonitoringK8s/Nodes/NodeDetails/NodeDetails.tsx
#	frontend/src/container/InfraMonitoringK8s/Nodes/utils.tsx
#	frontend/src/container/InfraMonitoringK8s/Pods/PodDetails/PodDetails.tsx
#	frontend/src/container/InfraMonitoringK8s/StatefulSets/StatefulSetDetails/StatefulSetDetails.tsx
#	frontend/src/container/InfraMonitoringK8s/StatefulSets/utils.tsx
#	frontend/src/container/InfraMonitoringK8s/Volumes/VolumeDetails/VolumeDetails.tsx
#	frontend/src/container/InfraMonitoringK8s/Volumes/utils.tsx
#	frontend/src/container/ListAlertRules/AlertsEmptyState/AlertsEmptyState.styles.scss
#	frontend/src/container/ListAlertRules/ListAlert.tsx
#	frontend/src/container/LogsContextList/styles.ts
#	frontend/src/container/LogsExplorerList/ColumnView/ColumnView.tsx
#	frontend/src/container/LogsExplorerViews/QueryStatus.tsx
#	frontend/src/container/MetricsApplication/Tabs/Overview/ApDex/ApDexTraces.tsx
#	frontend/src/container/MetricsExplorer/Explorer/RelatedMetrics.tsx
#	frontend/src/container/MetricsExplorer/Explorer/useGetRelatedMetricsGraphs.ts
#	frontend/src/container/MetricsExplorer/Summary/MetricTypeSearch.tsx
#	frontend/src/container/NewWidget/LeftContainer/QuerySection/QueryBuilder/ClickHouse/index.tsx
#	frontend/src/container/NewWidget/LeftContainer/QuerySection/QueryBuilder/ClickHouse/query.tsx
#	frontend/src/container/NewWidget/LeftContainer/QuerySection/QueryBuilder/clickHouse/index.tsx
#	frontend/src/container/NewWidget/LeftContainer/QuerySection/QueryBuilder/clickHouse/query.tsx
#	frontend/src/container/NewWidget/LeftContainer/QuerySection/QueryBuilder/datastore/index.tsx
#	frontend/src/container/NewWidget/LeftContainer/QuerySection/QueryBuilder/datastore/query.tsx
#	frontend/src/container/OnboardingQuestionaire/OnboardingFooter/OnboardingFooter.tsx
#	frontend/src/container/OnboardingQuestionaire/OnboardingHeader/OnboardingHeader.styles.scss
#	frontend/src/container/OnboardingQuestionaire/OnboardingHeader/OnboardingHeader.tsx
#	frontend/src/container/OnboardingV2Container/onboarding-configs/onboarding-config-with-links.json
#	frontend/src/container/QueryBuilder/QueryBuilder.tsx
#	frontend/src/container/QueryBuilder/components/Query/Query.tsx
#	frontend/src/container/RolesSettings/__tests__/utils.test.ts
#	frontend/src/container/ServiceTable/SkipOnBoardModal/index.tsx
#	frontend/src/container/TraceDetail/Missingtrace.tsx
#	frontend/src/container/TraceDetail/SelectedSpanDetails/config.ts
#	frontend/src/lib/uPlotV2/components/Tooltip/Tooltip.styles.scss
#	frontend/src/mocks-server/__mockdata__/apiKeys.ts
#	frontend/src/pages/AlertDetails/AlertHeader/AlertStatus/AlertStatus.tsx
#	frontend/src/pages/Integrations/IntegrationDetailPage/IntegrationDetailPage.styles.scss
#	frontend/src/pages/Integrations/IntegrationDetailPage/IntegrationDetailPage.tsx
#	frontend/src/pages/Integrations/IntegrationsList.tsx
#	frontend/src/pages/Integrations/utils.ts
#	frontend/src/types/api/integrations/aws.ts
#	pkg/alertmanager/o11yalertmanager/handler.go
#	pkg/apiserver/o11yapiserver/alertmanager.go
#	pkg/apiserver/o11yapiserver/cloudintegration.go
#	pkg/apiserver/o11yapiserver/inframonitoring.go
#	pkg/apiserver/o11yapiserver/llmpricingrule.go
#	pkg/apiserver/o11yapiserver/rawdataexport.go
#	pkg/apiserver/o11yapiserver/registry.go
#	pkg/apiserver/o11yapiserver/ruler.go
#	pkg/apiserver/o11yapiserver/ruler_examples.go
#	pkg/apiserver/o11yapiserver/ruler_examples_test.go
#	pkg/apiserver/o11yapiserver/rulestatehistory.go
#	pkg/apiserver/o11yapiserver/spanmapper.go
#	pkg/apiserver/o11yapiserver/tracedetail.go
#	pkg/authn/callbackauthn/googlecallbackauthn/authn.go
#	pkg/authz/openfgaauthz/provider.go
#	pkg/authz/openfgaschema/base.fga
#	pkg/authz/openfgaserver/server.go
#	pkg/authz/openfgaserver/server_test.go
#	pkg/authz/openfgaserver/sqlstore.go
#	pkg/http/middleware/api_key.go
#	pkg/http/middleware/authn.go
#	pkg/instrumentation/metric.go
#	pkg/modules/user/impluser/module.go
#	pkg/prometheus/clickhouseprometheus/client.go
#	pkg/prometheus/clickhouseprometheus/client_query_test.go
#	pkg/prometheus/clickhouseprometheus/provider.go
#	pkg/prometheus/config.go
#	pkg/prometheus/engine.go
#	pkg/prometheus/label.go
#	pkg/prometheus/prometheus.go
#	pkg/prometheus/prometheustest/provider.go
#	pkg/prometheus/prometheustest/utils_test.go
#	pkg/querier/promql_query.go
#	pkg/query-service/app/cloudintegrations/Readme.md
#	pkg/query-service/app/cloudintegrations/accountsRepo.go
#	pkg/query-service/app/cloudintegrations/constants.go
#	pkg/query-service/app/cloudintegrations/controller.go
#	pkg/query-service/app/cloudintegrations/models.go
#	pkg/query-service/app/cloudintegrations/serviceconfig_db.go
#	pkg/query-service/app/cloudintegrations/services/definitions/aws/eks/assets/dashboards/containerinsights.json
#	pkg/query-service/app/cloudintegrations/services/definitions/aws/eks/assets/dashboards/containerinsights_dot.json
#	pkg/query-service/app/cloudintegrations/services/definitions/aws/eks/assets/dashboards/overview.json
#	pkg/query-service/app/cloudintegrations/services/definitions/aws/eks/assets/dashboards/overview_dot.json
#	pkg/query-service/app/cloudintegrations/services/models.go
#	pkg/query-service/app/cloudintegrations/services/services.go
#	pkg/query-service/app/cloudintegrations/services/services_test.go
#	pkg/query-service/app/integrations/builtin_integrations/clickhouse/assets/dashboards/overview_dot.json
#	pkg/query-service/app/integrations/builtin_integrations/datastore/assets/dashboards/overview_dot.json
#	pkg/query-service/app/metricsexplorer/parser.go
#	pkg/query-service/app/metricsexplorer/summary.go
#	pkg/query-service/app/querier/querier_test.go
#	pkg/query-service/app/querier/v2/querier_test.go
#	pkg/query-service/app/summary.go
#	pkg/query-service/model/metrics_explorer/summary.go
#	pkg/query-service/rules/base_rule_test.go
#	pkg/query-service/rules/manager_test.go
#	pkg/query-service/rules/prom_rule.go
#	pkg/query-service/rules/prom_rule_task.go
#	pkg/query-service/rules/prom_rule_test.go
#	pkg/query-service/rules/threshold_rule_test.go
#	pkg/querybuilder/resourcefilter/tables.go
#	pkg/queryparser/queryfilterextractor/promql.go
#	pkg/ruler/o11yruler/handler.go
#	pkg/sqlmigration/088_migrate_ii_dashboards/clickhouse/overview.json
#	pkg/telemetrymetadata/metadata_test.go
#	pkg/telemetrystore/datastoretelemetrystore/telemetry.go
#	pkg/types/authtypes/name.go
#	pkg/types/authtypes/object.go
#	pkg/types/authtypes/selector.go
#	pkg/types/authtypes/typeable.go
#	pkg/types/authtypes/typeable_anonymous.go
#	pkg/types/authtypes/typeable_metaresource.go
#	pkg/types/authtypes/typeable_metaresources.go
#	pkg/types/authtypes/typeable_organization.go
#	pkg/types/authtypes/typeable_role.go
#	pkg/types/authtypes/typeable_user.go
#	pkg/types/authtypes/uuid.go
#	pkg/types/ctxtypes/auth.go
#	pkg/types/factor_api_key.go
#	pkg/types/integrationtypes/integration.go
#	pkg/types/roletypes/store.go
#	pkg/types/ruletypes/maintenance.go
#	pkg/types/serviceaccounttypes/service_account_role.go
#	pkg/types/serviceaccounttypes/store.go
2026-06-02 10:54:25 -07:00
Vinicius LourençoandGitHub a4d3f10da8 chore(codeowners): add pulse for alerts and infra monitoring pages (#11508) 2026-06-02 11:44:38 +00:00
Hanzo AI 9f561c87db merge: feat/cloud-mount
# Conflicts:
#	.github/workflows/build-ghcr.yaml
#	authn.go
#	cmd/enterprise/server.go
#	ee/query-service/app/api/api.go
#	ee/query-service/app/server.go
#	go.mod
#	pkg/query-service/rules/managertestfactory.go
2026-06-01 18:44:52 -07:00
Hanzo AI d485b4edaa merge: ci/shared-docker-workflow
# Conflicts:
#	.github/workflows/build-ghcr.yaml
2026-06-01 18:44:46 -07:00
Vikrant GuptaandGitHub b568f3e5cb chore(ci): remove unused frontend build variables (#11504) 2026-05-29 17:13:17 +00:00
Vikrant GuptaandGitHub d1f143f675 feat(web): add support for generating web settings types (#11445)
* feat(web): add support for generating settings type

* feat(web): add support for generating settings type

* feat(web): add support for generating settings type

* refactor: rename generate settings to generate config web-settings

- Rename cmd/settings.go to cmd/genconfig.go
- Restructure command as `generate config web-settings`
- Move schema output to docs/config/web-settings.json
- Update frontend script to generate:config:web-settings
- Update CI checks to match new command names
- Strip Web prefix from generated JSON Schema definitions
2026-05-25 12:41:24 +00:00
Ashwin BhatkalandGitHub c3db819d8e chore: update code owners for dashboard v2 and e2e (#11412)
* chore: update code owners for dashboard and e2e

* chore: update code owners order
2026-05-22 13:19:04 +00:00
Hanzo AI 99a577786f ci: amd64 only + id-token write
DOKS has no arm64 droplets (hanzo-build-linux-arm64 ARC paused). Default
shared workflow builds both arches and arm64 queues forever (24h timeout).
Caller permissions are also the ceiling for reusable workflow — without
id-token: write at top level dispatch dies as startup_failure.
2026-05-18 23:30:28 -07:00
Vinicius LourençoandGitHub c86df3adcb feat(pnpm): migrate away from yarn (#11158)
* feat(pnpm): migrate away from yarn

* fix(lodash): using uninstall dependency

* fix(workflows): use pnpm as package manager

* fix(pnpm-lock): keep it updated

* fix(test): issue with lodash-es and our pnpm store

* fix(jest): more esm conflicts

* fix(pipeline-page): update snapshot test

* fix(pnpm-lock): out of sync

* fix(json-view): issue with typing

* chore(pnpm): upgrade pnpm

* chore(yarn): remove yarn
2026-05-12 12:25:21 +00:00
Vikrant GuptaandGitHub 0aaf556137 Update CODEOWNERS (#11192) 2026-05-05 14:11:58 +00:00
3d8cddf84e refactor: split typeable infrastructure into pkg/types/coretypes (#11105)
* refactor: move authtypes to coretypes

* refactor: migrate downstream consumers to coretypes Kind/Type/Relation

Wire all consumers of the typeable infrastructure through coretypes:
- Replace authtypes.Name/Type/Relation references with coretypes equivalents
- Switch Typeable singletons to constructor calls (authtypes.NewTypeableUser
  etc.), with the embedded coretypes.Typeable populated so Kind/Type/Prefix/
  Scope dispatch correctly through the embed
- Update dashboardtypes meta-resource declarations to use authtypes
  constructors so they expose Tuples (authz callers need it)
- Rename Resource.Name field accesses to Resource.Kind to match the field
  rename in authtypes.Resource
- Fix typeable_metaresource.go calling the plural NewTypeableMetaResources
  helper — should be the singular NewTypeableMetaResource

go build ./... and go vet ./... clean (parser-generated unreachable-code
warnings are pre-existing). Authz unit tests pass.

* refactor(audittypes): unify Action with coretypes.Relation

Drop the duplicate Action enum from audittypes — the verbs (create/update/
delete) match coretypes.Relation exactly. Move PastTense onto Relation so
audit EventName derivation continues to work without a parallel hierarchy.

Also retypes AuditDef.ResourceKind from string to coretypes.Kind so audit
declarations get the same regex validation that authz already enforces.

* refactor(retentiontypes): extract TTLSetting into its own package

TTLSetting is the bun model for ClickHouse TTL settings — has nothing to do
with the Organization domain it was previously co-located with in
pkg/types/organization.go. Moved to pkg/types/retentiontypes/ alongside the
ClickHouse reader that's its sole consumer.

No schema change; the bun table tag (table:ttl_setting) is unchanged.

* chore(openapi): regenerate spec for coretypes.Relation and Resource.Kind

* chore(frontend): regenerate API client and migrate Resource.name → Resource.kind

Regenerated TypeScript API types after the AuthtypesResource field rename
and the new CoretypesRelation enum. Updated:

- frontend/scripts/generate-permissions-type.cjs to read `r.kind` from the
  /api/v1/authz/resources response and emit `kind:` in the static
  permissions.type.ts file.
- frontend/src/hooks/useAuthZ/{permissions.type,types,utils,useAuthZ}.tsx:
  Resource.name → Resource.kind throughout.
- frontend/src/container/RolesSettings/{utils.tsx,__tests__/utils.test.ts}:
  same field migration.
- frontend/src/components/createGuardedRoute/createGuardedRoute.test.tsx:
  same.
- useAuthZ/utils.ts: cast string relations to CoretypesRelationDTO at the
  AuthtypesTransactionDTO boundary now that relation is an enum, not a raw
  string.

yarn generate:api passes (orval generation + lint + typecheck).

* refactor: migrate downstream consumers to Resource/Verb rename

* chore(openapi): regenerate spec for Resource/Verb rename

* feat(coretypes): add ListResources accessor with stable sort

* feat(cmd): add 'generate authz' subcommand for permissions type

* refactor(authz): drop runtime authz/resources endpoint

* refactor(frontend): consume static permissions.type.ts directly

* chore(frontend): regenerate Orval client without authz/resources

* ci: move authz schema check from jsci to goci

* refactor(coretypes): move Selector/Object/Transaction from authtypes

* feat(coretypes): add managed role names and permission policy

* feat(coretypes): add Registry assembling resources, types, and managed-role transactions

* refactor(authz): wire *coretypes.Registry; drop RegisterTypeable

* refactor(cmd): wire coretypes.NewRegistry into server bootstraps

* chore: regenerate openapi spec for authtypes -> coretypes type moves

* chore(frontend): regenerate API client for Authtypes -> Coretypes type moves

* refactor(coretypes): rename GettableResource to ResourceRef

* refactor(authz): collapse Registry around static data; bridge once at construction

* refactor(coretypes): tighten Registry, restore anonymous public-dashboard grant

Drops passthrough fields from coretypes.Registry; adds an O(1) lookup map
for NewResourceFromTypeAndKind; replaces stringly-typed Type compares with
Type.Equals; removes the now-redundant getUniqueTypes helper. Restores the
signoz-anonymous read grant on metaresource/public-dashboard that was
silently dropped, and removes the invalid signoz-admin/VerbCreate/TypeUser
entry that panicked at startup.

* chore: regenerate openapi spec for coretypes -> authtypes type moves

* chore(frontend): regenerate API client for Coretypes -> Authtypes type moves

* fix(authz): disambiguate kind→type by relation, preserve multi-part selectors

permissions.type.ts now lists the same kind (dashboard, role,
public-dashboard) under both metaresource and metaresources, so the prior
kind→type map silently overwrote one with the other. Resolve the type
using the requesting relation's allowed types, and slice the selector at
the first colon so multi-part selectors (e.g. id:version) round-trip
correctly. Updates useAuthZ.test.tsx to use the regenerated kind field.

* refactor(authtypes): introduce Relation wrapper over coretypes.Verb

The authz layer modeled relations as raw coretypes.Verb everywhere, which
forced authz-level concepts (action, role-binding) to share a type with
schema-level enumerations. Introduce authtypes.Relation as a thin wrapper
over coretypes.Verb so the authz APIs (CheckWithTupleCreation, ListObjects,
GetObjects, PatchObjects, NewTuples, Transaction.Relation, etc.) can grow
authz-specific affordances without leaking back into coretypes.

Also reshuffles the static coretypes data into dedicated registry_*.go files
(types, kinds, verbs, resources, managed roles) to keep the schema declarations
isolated from the value types they configure.

* refactor(authtypes): expose Relation.Enum() and regenerate openapi spec

Without an Enum() method on Relation the openapi generator emitted an
empty AuthtypesRelation schema (no allowed values). Forward the enum
from the embedded coretypes.Verb so the wire contract is faithful.

* refactor(ee/authz): drop always-nil error returns from managed-role tuple helpers

getManagedRoleGrantTuples and getManagedRoleTransactionTuples never
returned a non-nil error, which the linter (unparam) had flagged. Drop
the unused error return; callers no longer need the err check either.

* chore(frontend): regenerate API client for authtypes.Relation

* fix(authz): satisfy go-lint — keyed Relation literal, drop redundant Verb selector

* refactor(coretypes): sync Kinds slice with full registry_kind declarations

* feat(coretypes): register metaresource and metaresources for all new kinds

Adds 21 metaresource and 21 metaresources entries (covering notification-channel,
route-policy, apdex-setting, auth-domain, session, cloud-integration,
cloud-integration-service, ingestion-key, ingestion-limit, pipeline,
user-preference, org-preference, quick-filter, ttl-setting, rule,
planned-maintenance, saved-view, trace-funnel, factor-password, factor-api-key,
license) so the authz schema covers every resource Kind declared in
registry_kind. Regenerates the static frontend permissions.type.ts to match.

* feat(coretypes): populate ManagedRoleToTransactions from signozapiserver routes

Enumerates every (verb, resource) tuple each managed role holds, derived
from the AdminAccess/EditAccess/ViewAccess middleware on routes in
pkg/apiserver/signozapiserver and the legacy http_handler in
pkg/query-service/app. Admin gets 123 transactions, editor 53, viewer 25,
anonymous keeps the single public-dashboard read.

* feat(coretypes): add integration kind with full CRUD for viewer/editor/admin

Install/uninstall/list integration routes (legacy /api/v1/integrations) all
sit behind ViewAccess, so every authenticated role gets the full CRUD
surface on (metaresource, integration) and (metaresources, integration).
Regenerates the static frontend permissions.type.ts to match.

* feat(coretypes): add subscription kind alongside license, document LCRUD shape

License covers the in-product license resource (Activate/Refresh/GetActive).
Subscription is the billing lifecycle (checkout/portal/billing) served by
ee/query-service routes. Both are admin-only and modeled with a uniform
LCRUD shape; comments call out which verbs actually map to routes versus
which are placeholders for shape parity (e.g. cancellation flows through
Stripe's portal, not an in-process delete).

* feat(coretypes): model telemetryresource for logs, traces, metrics

Mirrors the telemetryresource type from ee/authz/openfgaschema/base.fga
into coretypes: a read-only Type with three Kinds (logs, traces, metrics)
matching telemetrytypes.Signal. Selector is wildcard-only for v1; future
work can narrow per-service or per-environment when the use case lands.
Every managed role (admin/editor/viewer) gets read on each signal,
matching the schema's role#assignee grant. Anonymous stays unchanged.
Regenerates the static frontend permissions.type.ts.

* feat(coretypes): add audit-logs and meter-metrics kinds under telemetryresource

Audit logs (signal=logs, source=audit) and meter metrics (signal=metrics,
source=meter) are sensitive source-qualified telemetry streams that don't
belong under the broad read-grant every role gets on regular logs/traces/
metrics. Modeled as distinct Kinds so they can be permissioned
independently. Admin-only read for now; widen on explicit ask (e.g. an
auditor flow that needs viewer access to audit-logs). Regenerates the
static frontend permissions.type.ts.

* feat(coretypes): add logs-field and traces-field kinds for stored field config

GET/POST /logs/fields and /api/v2/traces/fields manage stored, mutable
field metadata (indexed/promoted columns) over each signal. They're
configuration, not telemetry data, so they sit under metaresource rather
than telemetryresource. Viewer reads, editor/admin update; no
create/delete since POST overwrites. Plural prefix (logs-field /
traces-field) matches the signal naming.

* chore(frontend): regenerate permissions.type.ts to match generate authz output

* feat(authz): add attach permissions to fga model

* fix(tests): use role permissions instead of dashboards

* fix(authz): couple of issues with register flow

* fix(authz): public dashboard read should be anomymous

* fix(tests): integration test for public dashboard access

---------

Co-authored-by: vikrantgupta25 <vikrant@signoz.io>
2026-05-05 19:13:09 +05:30
PandeyandGitHub 3f95d35ad5 chore: add @therealpandey with @srikanthcvv (#11126)
#### Temporary

- add @therealpandey with @srikanthcvv
2026-04-28 10:01:39 +00:00
Piyush SingariyaandGitHub 9e5678d6b3 CI: JSON QB E2E Integration Suite (#10863)
* feat: enable JSON Path index

* fix: contextual path index usage

* test: fix unit tests

* feat: align negative operators to include other logs

* fix: primitive conditions working

* fix: indexed tests passing

* fix: array type filtering from dynamic arrays

* fix: unit tests

* fix: remove not used paths from testdata

* fix: unit tests

* fix: comment

* fix: indexed unit tests

* fix: array json element comparison

* feat: change filtering of dynamic arrays

* fix: dynamic array tests

* fix: stringified integer value input

* fix: better review for test file

* fix: negative operator check

* ci: lint changes

* chore: import tests from older pr

* fix: better tests

* fix: logs.py

* fix: body tests ready

* fix: better validations

* fix: dynamically change insert stmt for body_v2 availability

* test: with higher migrator version

* fix: type ambiguity

* fix: test

* test: updated validation

* fix: tons of changes

* chore: remove redundent comparison

* ci: tests fixed

* fix: upgraded collector version

* fix: qbtoexpr tests

* fix: go sum

* chore: upgrade collector version v0.144.3-rc.4

* fix: tests

* ci: test fix

* revert: remove db binaries

* test: selectField tests added

* fix: added safeguards in plan generation

* fix: name changed to field_map

* chore: changes based on review

* fix: changes based on review

* fix: remove unused promoted fixture

* test: integration test fix attempt 1

* fix: json access plan remval of AvailableTypes

* fix: invalid index usage on terminal condition

* test: added indexed tests separately

* test: select order by tests added

* fix: update jsontypeexporter

* fix: branches should tell missing array types

* fix: comment removed

* ci: test with updated collector

* fix: issue with FuzzyMatching and API failing

* test: select orderby works

* fix: int64 mapping

* fix: replacing JSONIndex with TelemetryFieldKeyIndex

* chore: update collector to stable release

* chore: update migrator version to stable release

* chore: error fix and unused code

* chore: go mod tidy

* chore: some changes in test to improve quality

* test: enhanced tests to work with backtick required key

* chore: comment removal

* fix: change based on review

* fix: change based on review

* fix: openapi ci

* ci: fix go tests

* fix: index needs body prefix

* fix: tests

* ci: polluted test fix

* fix: shift test files

* refactor(telemetrytypes): replace JSONDataTypeIndex with TelemetryFieldKeySkipIndex

* revert: mcp related changes

* feat: check query log as fixture

* fix: reuse querier fixtures

* chore: rename jsontypeexporter.py

* chore: py-fmt

* fix: minor fix

* fix: py-lint

* fix: changes based on review

* chore: fmt
2026-04-28 08:49:44 +00:00
Hanzo DevandGitHub 17a4c164d4 ci: canonical docker-build (#2)
* feat: add /v1/o11y/* rewrite middleware for standard API path convention

Add URL rewrite middleware that intercepts /v1/o11y/* requests and
rewrites them to /api/* internally, allowing external clients to use
the /<version>/<service>/<path> convention while keeping all existing
internal route registrations unchanged.

* chore: sync latest

* ci: migrate to canonical hanzoai/.github/docker-build.yml reusable
2026-04-23 19:24:27 -07:00
Hanzo AI 44130eb718 ci: migrate to canonical hanzoai/.github/docker-build.yml reusable 2026-04-23 19:17:50 -07:00
PandeyandGitHub f62024ad3f chore: modern fmts and lints for tests/ (#11074)
* chore(frontend): remove stale e2e scaffold

frontend/e2e/ held an unused settings-only test-plan scaffold from Oct 2025.
Active Playwright specs live at tests/e2e/. Drop the directory, the orphan
playwright.config.ts, the @playwright/test dependency, and the tsconfig
references that pinned them.

* chore(e2e): migrate formatter from prettier to oxfmt

Swap tests/e2e/ onto oxfmt — same tool the frontend adopted in #11057. Style
matches frontend/.oxfmtrc.json (tabs, tabWidth:1) so the two TS trees stay
visually consistent. Drops .prettierrc.json and .prettierignore, adds the
fmt/fmt:check yarn scripts, and reformats the existing specs.

* chore(e2e): migrate linter from eslint to oxlint

Drop eslint + @typescript-eslint plugins in favour of oxlint 1.59 + tsgolint
— same toolchain the frontend adopted in #10176. The .oxlintrc.json mirrors
frontend/.oxlintrc.json with plugins scoped to a Playwright TS codebase
(eslint, typescript, unicorn, import, promise).

Divergence: eslint-plugin-playwright is not ported. Its rules depend on
ESLint APIs (context.getAncestors) that oxlint's JS plugin shim does not
implement, so the five playwright/* rules are dropped in this migration.

* ci(e2e): add fmtlint job

Mirror integrationci.yaml's fmtlint job for e2e. Runs oxfmt --check and
oxlint on tests/e2e/ under the same safe-to-e2e label gating as the
existing test job.

* chore(integration): migrate python tooling from black/pylint/isort/autoflake to ruff

Replace the four-tool stack with ruff — same motivation as the oxfmt/oxlint
swap on the TS side. One tool covers formatting (ruff format), import
sorting (I), unused-import/variable cleanup (F401/F841), and the pylint
rules we actually care about (E/W/F/UP/B/PL).

Rule set mirrors the intent of the prior pylint config: too-many-* checks
and magic-value-comparison stay disabled, dangerous-default-value (now
B006) stays muted. A handful of newly-surfaced codes (B011/B024/B905/E741/
UP047/PLC0206/PLW2901) are also muted to keep this a pure tool swap — each
deserves its own review before enabling.

Divergence: ruff caps line-length at 320, so the prior pylint value of 400
drops to 320. Nothing in tree exceeds 320, so no lines wrap.

No changes to integrationci.yaml — both fmt/lint steps still call
make py-fmt / make py-lint, which now dispatch to ruff.

* chore(e2e): restore playwright lint rules via oxlint jsPlugin

eslint-plugin-playwright@2.x was rewritten against ESLint 8's
context.sourceCode.getAncestors() API, which oxlint's JS plugin shim
exposes. The 0.16.x version previously ruled out by context.getAncestors()
missing is no longer a blocker. Bump to 2.10.2, re-add it as a jsPlugin,
and restore the five rules dropped in the initial oxlint migration:
expect-expect, no-conditional-in-test, no-page-pause, no-wait-for-timeout,
prefer-web-first-assertions.

Rule count: 104 → 109.

* chore(frontend): remove stale e2e prompt

frontend/prompts/generate-e2e-test.md is leftover from the same Oct 2025
scaffold removed in ebf735dcc. It references frontend/e2e/utils/login.util.ts,
which no longer exists, and is not wired into anything.

* chore(e2e): make .env.local write layout explicit

The single f-string with inline \n escapes read as a wall of text after
ruff's line-length allowance collapsed it onto one line. Switch to a
triple-quoted f-string so the generated .env.local structure is visible
in source. Byte-for-byte identical output.

* chore(e2e): write .env.local one key per line

Open the file with a context manager and emit each key with its own
f.write call. Same output as before, but each key-value pair is a
discrete statement.
2026-04-23 12:01:42 +00:00
PandeyandGitHub 93f5df9185 tests: unify integration + e2e under shared pytest project (#11019)
* refactor(tests): hoist pytest project to tests/ root for shared fixtures

Lift pyproject.toml, uv.lock, conftest.py, and fixtures/ up from
tests/integration/ so the pytest project becomes shared infrastructure
rather than integration's private property. A sibling tests/e2e/ can
reuse the same fixture graph (containers, auth, seeding) without
duplicating plugins.

Also:
- Merge tests/integration/src/querier/util.py into tests/fixtures/querier.py
  (response assertions and corrupt-metadata generators belong with the
  other querier helpers).
- Use --import-mode=importlib + pythonpath=["."] in pyproject so
  same-basename tests across src/*/ do not collide at the now-wider
  rootdir.
- Broaden python_files to "*/src/**/**.py" so future test trees under
  tests/e2e/src/ get discovered.
- Update Makefile py-* targets and integrationci.yaml to cd into tests/
  and reference integration/src/... paths.

* feat(tests/e2e): import Playwright suite from signoz-e2e

Relocate the standalone signoz-e2e repository into tests/e2e/ as a
sibling of tests/integration/. The suite still points at remote
staging by default; subsequent commits wire it to the shared pytest
fixture graph so the backend can be provisioned locally.

Excluded from the import: .git, .github (CI migration deferred),
.auth, node_modules, test-results, playwright-report.

* feat(tests/e2e): pytest-driven backend bring-up, seeding, and playwright runner

Wire the Playwright suite into the shared pytest fixture graph so the
backend + its seeded state are provisioned locally instead of pointing
at remote staging.

Python side (owns lifecycle):
- tests/fixtures/dashboards.py — generic create/list/upsert_dashboard
  helpers (shared infra; testdata stays per-tree).
- tests/e2e/conftest.py — e2e-scoped pytest fixtures: seed_dashboards
  (idempotent upsert from tests/e2e/testdata/dashboards/*.json),
  seed_alert_rules (from tests/e2e/testdata/alerts/*.json, via existing
  create_alert_rule), seed_e2e_telemetry (fresh traces/logs across a
  few synthetic services so /home and Services pages have data).
- tests/e2e/src/bootstrap/setup.py — test_setup depends on the fixture
  graph and persists backend coordinates to tests/e2e/.signoz-backend.json;
  test_teardown is the --teardown target.
- tests/e2e/src/bootstrap/run.py — test_e2e: one-command entrypoint that
  brings up the backend + seeds, then subprocesses yarn test and asserts
  Playwright exits 0.
- tests/conftest.py — register fixtures.dashboards plugin.

Playwright side (just reads):
- tests/e2e/global.setup.ts — loads .signoz-backend.json and injects
  SIGNOZ_E2E_BASE_URL/USERNAME/PASSWORD. No-op when env is already
  populated (staging mode, or pytest-driven runs where env is pre-set).
- playwright.config.ts registers globalSetup.
- package.json gains test:staging; existing scripts unchanged.

Testdata layout: tests/e2e/testdata/{dashboards,alerts,channels}/*.json
— per-tree (integration has its own tests/integration/testdata/).

* docs(tests): describe pytest-master workflow and shared fixture layout

- tests/README.md (new): top-level map of the shared pytest project,
  fixture-ownership rule (shared vs per-tree), and common commands.
- tests/e2e/README.md: lead with the one-command pytest run and the
  warm-backend dev loop; keep the staging fallback as option 2.
- tests/e2e/CLAUDE.md: updated commands so agent contexts reflect the
  pytest-driven lifecycle.
- tests/e2e/.env.example: drop unused SIGNOZ_E2E_ENV_TYPE; note the file
  is only needed for staging mode.

* fix(tests/fixtures/signoz.py): anchor Docker build context to repo root

Previously used path="../../" which resolved to the repo root only when
pytest's cwd was tests/integration/. After hoisting the pytest project
to tests/, that same relative path pointed one level above the repo
root and the build failed with:

  Cannot locate specified Dockerfile: cmd/enterprise/Dockerfile.with-web.integration

Anchor the build context to an absolute path computed from __file__ so
the fixture works regardless of pytest cwd.

* feat(tests/e2e): alerts-downtime regression suite (platform-pod/issues/2095)

Import the 34-step regression suite originally developed on
platform-pod/issues/2095-frontend. Targets the alerts and planned-downtime
frontend flows after their migration to generated OpenAPI clients and
generated react-query hooks.

- specs/alerts-downtime/: SUITE.md (the stable spec), README.md (scope +
  open observations from the original runs), results-schema.md (legacy
  per-run artifact shape, retained for context).
- tests/alerts-downtime/alerts-downtime.spec.ts: 881-line Playwright spec
  covering 6 flows — alert CRUD/toggle, alert detail 404, planned
  downtime CRUD, notification channel routing, anomaly alerts.

Integration with the shared suite:
- Uses baseURL + storageState from tests/e2e/playwright.config.ts (no
  separate config). page.goto calls use relative paths; SIGNOZ_E2E_*
  env vars from the pytest bootstrap drive auth.
- test.describe.configure({ mode: 'serial' }) at the top of the describe:
  the flows mutate shared tenant state, so parallel runs cause cross-
  flow interference (documented in the original 2095 config).
- Per-run artifacts (network captures + screenshots) land in
  tests/e2e/tests/alerts-downtime/run-spec-<ts>/ by default — gitignored.

Historical per-run artifacts (~7.5MB of screenshots across run-1 through
run-7) are not imported; they lived at e2e/2095/run-*/ on the original
branch and remain there if needed.

* refactor(fixtures/traces): extract insert + truncate helpers

Pull the ClickHouse insert path out of the insert_traces pytest fixture
into a plain module-level function insert_traces_to_clickhouse(conn,
traces), and move the per-table TRUNCATE loop into truncate_traces_tables
(conn, cluster). The fixture becomes a thin wrapper over both — zero
behavioural change.

Lets the HTTP seeder container (tests/fixtures/seeder/) reuse the exact
same insert + truncate code the pytest fixture uses, so the two stay in
sync as the trace schema evolves.

* feat(fixtures/seeder): HTTP seeder container for fine-grained telemetry seeding

Adds a sibling container alongside signoz/clickhouse/postgres that exposes
HTTP endpoints for direct-ClickHouse telemetry seeding, so Playwright
tests can shape per-test data without going through OTel or the SigNoz
ingestion path.

tests/fixtures/seeder/:
- Dockerfile: python:3.13-slim + the shared fixtures/ tree so the
  container can import fixtures.traces and reuse the exact insert path
  used by pytest.
- server.py: FastAPI app with GET /healthz, POST /telemetry/traces
  (accepts a JSON list matching Traces.from_dict input; auto-tags each
  inserted row with resource seeder=true), DELETE /telemetry/traces
  (truncates all traces tables).
- requirements.txt: fastapi, uvicorn, clickhouse-connect, numpy plus
  sqlalchemy/pytest/testcontainers because fixtures/{__init__,types,
  traces}.py import them at module load.

tests/fixtures/seeder/__init__.py: pytest fixture (`seeder`, package-
scoped) that builds the image via docker-py (testcontainers DockerImage
had multi-segment dockerfile issues), starts the container on the
shared network wired to ClickHouse via env vars, and waits for
/healthz. Cache key + restore follow the dev.wrap pattern other
fixtures use for --reuse.

tests/.dockerignore: exclude .venv, caches, e2e node_modules, and test
outputs so the build context is small and deterministic.

tests/conftest.py: register fixtures.seeder as a pytest plugin.

Currently traces-only — logs + metrics follow the same pattern.

* feat(tests/e2e): surface seeder_url to Playwright via globalSetup

- bootstrap/setup.py: test_setup now depends on the seeder fixture and
  writes seeder_url into .signoz-backend.json alongside base_url.
- bootstrap/run.py: test_e2e exports SIGNOZ_E2E_SEEDER_URL to the
  subprocessed yarn test so Playwright specs can reach the seeder
  directly in the one-command path.
- global.setup.ts: if .signoz-backend.json carries seeder_url, populate
  process.env.SIGNOZ_E2E_SEEDER_URL. Remains optional — staging mode
  leaves it unset.

Playwright specs that want per-test telemetry can:
  await fetch(process.env.SIGNOZ_E2E_SEEDER_URL + '/telemetry/traces', {
    method: 'POST',
    headers: { 'Content-Type': 'application/json' },
    body: JSON.stringify([...])
  });
and await a truncate via DELETE on teardown.

* fix(alerts-downtime): capture load-time GETs before navigation

Flow 1 registered cap.mark() AFTER page.goto() and then called
page.waitForResponse(/api/v2/rules) — but against a fast local backend
the GET /api/v2/rules response arrived during page.goto, before the
waiter could register, and the test timed out at 30s.

installCapture's page.on('response') listener runs from before the
navigation, so moving mark() above page.goto() and relying on
dumpSince's 500ms drain is enough. No lost precision.

One site only; the same pattern exists in later flows (via per-action
waitForResponse) and may surface similar races — those are left for a
follow-up once the backend-side 2095 migration lands on main (current
frontend still calls PATCH /api/v1/rules/:id which the spec's assertion
doesn't match anyway).

* refactor(fixtures/logs,metrics): extract insert + truncate helpers

Mirror the traces refactor: pull the ClickHouse insert path out of the
insert_logs / insert_metrics pytest fixtures into plain module-level
functions (insert_logs_to_clickhouse, insert_metrics_to_clickhouse) and
move the per-table TRUNCATE loops into truncate_logs_tables /
truncate_metrics_tables. The fixtures become thin wrappers — zero
behavioural change.

Sets up the seeder container to expose POST/DELETE endpoints for logs
and metrics using the exact same code paths as the pytest fixtures.

* feat(fixtures/seeder): add logs and metrics endpoints

Extend the seeder with POST/DELETE endpoints for logs and metrics,
following the same shape as the existing traces endpoints:

- POST /telemetry/logs accepts a JSON list matching Logs.from_dict;
  tags each row's resources with seeder=true.
- POST /telemetry/metrics accepts a JSON list matching Metrics.from_dict;
  tags resource_attrs with seeder=true (Metrics.from_dict unpacks
  resource_attrs rather than a resources dict).
- DELETE /telemetry/logs, DELETE /telemetry/metrics truncate via the
  shared truncate_*_tables helpers.

Requirements gain svix-ksuid because fixtures/logs.py imports KsuidMs
for log id generation.

Verified end-to-end against the warm backend: POST inserted=1 on each
signal, DELETE truncated=true on each.

* refactor(fixtures/seeder): align status codes with HTTP semantics

- POST /telemetry/{traces,logs,metrics}: return 201 Created (kept the
  {inserted: N} body so callers can verify the count landed).
- DELETE /telemetry/{traces,logs,metrics}: return 204 No Content with
  an empty body.

* refactor(tests/seeder): extract from fixtures/ into top-level package

Move the HTTP seeder (Dockerfile, requirements.txt, server.py) out of
tests/fixtures/seeder/ and into its own tests/seeder/ top-level package.
The pytest fixture that builds and runs the image moves to
tests/fixtures/seeder.py so it sits next to the other container fixtures.

Rationale: the seeder is a standalone containerized Python service, not a
pytest fixture. It ships a Dockerfile, its own requirements.txt, and a
server.py entrypoint — none of which belong under a package whose purpose
is shared pytest code.

Image-side changes:
- Dockerfile now copies seeder/ alongside fixtures/ and launches
  seeder.server:app instead of fixtures.seeder.server:app.
- Build context stays tests/ (unchanged), so fixtures.* imports inside
  server.py continue to resolve.

Fixture-side changes:
- _TESTS_ROOT computation drops one parent (parents[1] now that the file
  is at tests/fixtures/seeder.py, not tests/fixtures/seeder/__init__.py).
- The dockerfile= path passed to docker-py becomes seeder/Dockerfile.

No behavior change; every consumer still imports the seeder fixture as
before and gets the same container.

* refactor(fixtures/keycloak): rename from idp.py to name the concrete tech

The container provider at fixtures/idp.py brought up a Keycloak image. Name
it for what it is so we can use fixtures/idp.py later for API-side IdP
helpers (OIDC/SAML admin flows) without an idp-vs-idputils naming collision.

- fixtures/idp.py → fixtures/keycloak.py (git rename).
- fixtures.idputils updates its one internal import to fixtures.keycloak.
- conftest.py pytest_plugins entry points at the new module.

No caller outside fixtures/ imports fixtures.idp directly, so no shim is
needed. The "idp" fixture name (how tests reference it) is unchanged.

* refactor(fixtures/gateway): drop -utils suffix

The module only held helper functions (no fixtures). Rename to match the
domain and leave a shim at the old path so integration/ import sites keep
working until they are swept in a follow-up.

* fix(fixtures/gatewayutils): silence wildcard-import in deprecation shim

The shim intentionally re-exports via `from fixtures.gateway import *`;
pylint flags the wildcard and every unused-wildcard symbol. Suppress both
in the shim only — the live module has no wildcard.

* refactor(fixtures/auth): merge authutils helpers into auth

Pull the pure-helper functions from authutils.py (create_active_user,
find_user_by_email, find_user_with_roles_by_email, assert_user_has_role,
change_user_role) into auth.py next to the fixtures they complement.
Fixtures remain on top; helpers go below. Drop the module docstring.

Replace authutils.py with a deprecation shim that re-exports from
fixtures.auth so integration/ import sites (9 files) keep working until
they are swept in a follow-up. Suppress the wildcard-import warnings in
the shim only.

* refactor(fixtures/alerts): merge alertutils helpers into alerts

Pull the pure-helper functions from alertutils.py
(collect_webhook_firing_alerts, _verify_alerts_labels,
verify_webhook_alert_expectation, update_rule_channel_name) into alerts.py
next to the fixtures they complement. Fixtures stay on top; helpers go
below.

Replace alertutils.py with a deprecation shim that re-exports from
fixtures.alerts so integration/ import sites keep working until they are
swept in a follow-up.

* refactor(fixtures/cloudintegrations): merge cloudintegrationsutils helpers

Pull the pure-helper functions from cloudintegrationsutils.py
(deprecated_simulate_agent_checkin, setup_create_account_mocks,
simulate_agent_checkin) into cloudintegrations.py next to the fixtures
they complement. Fixtures stay on top; helpers go below.

Replace cloudintegrationsutils.py with a deprecation shim that re-exports
from fixtures.cloudintegrations so integration/ import sites keep working
until they are swept in a follow-up.

* refactor(fixtures/idp): rename idputils to idp now that keycloak owns the container

With the Keycloak container provider at fixtures.keycloak, the fixtures.idp
name is free for what idputils always was — API/browser helpers for OIDC
and SAML admin flows against the IdP container.

- fixtures.idputils → fixtures.idp (git rename).
- conftest.py pytest_plugins swaps fixtures.idputils for fixtures.idp so
  the create_saml_client / create_oidc_client fixtures register under the
  canonical path.

Replace fixtures.idputils with a deprecation shim re-exporting from
fixtures.idp so integration/ import sites (callbackauthn) keep working
until they are swept in a follow-up.

* refactor(fixtures/reuse): rename from dev to describe what the module is

The module wraps pytest-cache resource reuse/teardown for container
fixtures; "dev" conveyed nothing about its role. Rename to fixtures.reuse
and update the 12 internal callers that imported `from fixtures import
dev, types` to use `reuse` instead.

Replace fixtures.dev with a deprecation shim so any external caller keeps
working until the follow-up sweep.

* refactor(fixtures/time,fs): split utils by responsibility

fixtures.utils only held two time parsers (parse_timestamp, parse_duration)
and one path helper (get_testdata_file_path) — a "utils" grab bag.

- Time parsers move to fixtures.time (utils.py → time.py via git rename).
- get_testdata_file_path moves into fixtures.fs where other filesystem
  helpers live.
- Internal callers (alerts, logs, metrics, traces) update to the new paths.

Replace fixtures.utils with a deprecation shim that re-exports all three
functions so integration/ import sites keep working until the follow-up
sweep.

* refactor(fixtures/browser): rename from driver to match peer primitives

fixtures.driver was the Selenium WebDriver fixture — rename the module to
fixtures.browser so it sits next to fixtures.http as a named primitive.
The fixture name inside (driver) stays — that's the Selenium-canonical
term and tests reference it directly.

conftest.py pytest_plugins entry points at the new module. A deprecation
shim at fixtures.driver keeps any external caller working until the
follow-up sweep.

* refactor(tests/seeder): install deps via uv from pyproject, drop requirements.txt

The seeder's requirements.txt duplicated 7 of 10 deps from pyproject.toml
with overlapping version pins — a standing drift risk. The comment on top
of the file admitted the real problem: the seeder image already ships
pytest + testcontainers + sqlalchemy because importing fixtures.traces
walks fixtures/__init__.py and fixtures/types.py. "Don't ship test infra"
was already violated.

- Add fastapi, uvicorn[standard], and py to pyproject.toml dependencies
  (the three seeder-only deps that were not yet in pyproject; `py` was a
  latent gap since fixtures/types.py uses py.path.local but pytest only
  pulls it in transitively).
- Switch the Dockerfile to `uv sync --frozen --no-install-project --no-dev`
  so the container env matches local dev exactly (uv.lock is the single
  source of truth for versions).
- Move tests/seeder/Dockerfile → tests/Dockerfile.seeder so it lives
  alongside the pyproject at the root of the build context.
- Delete tests/seeder/requirements.txt.

The seeder image grows by ~40-50MB (selenium, psycopg2, wiremock now come
along from main deps); accepted as a cost of single source of truth since
the seeder is dev-only infra, not a shipped artifact.

* refactor(tests/integration): flatten src/ into bootstrap/ + tests/

Drop the redundant src/ layer in the integration tree. 'src' carries no
information — the directory IS integration test source. After flatten:

  tests/integration/
    bootstrap/setup.py        was src/bootstrap/setup.py
    tests/<suite>/*.py        was src/<suite>/*.py (16 suites)
    testdata/

Updates:
- Makefile: py-test-setup/py-test-teardown/py-test target paths.
- tests/README.md: layout diagram + command examples.
- tests/pyproject.toml: python_files glob now matches basenames
  explicitly — "[0-9][0-9]_*.py" for NN-prefixed suite files plus
  "setup.py" and "run.py" for bootstrap entrypoints. The old "*/src/.."
  glob stopped matching anything here and would have caused pytest to
  try collecting seeder/server.py as a test.

* refactor(tests/e2e): flatten src/ into bootstrap/

Drop the e2e/src/ wrapper — the only Python content under it was
bootstrap/, which is now a direct child of e2e/. Keeps integration and
e2e symmetric (both have bootstrap/, tests/, testdata/ as peers).

Also delete bootstrap/__init__.py on both integration and e2e sides.
With --import-mode=importlib, pytest walks up from each .py file to find
the highest __init__.py-containing dir and uses that as the package root.
Without integration/__init__.py or e2e/__init__.py above bootstrap/, both
setup.py files resolved to the same dotted name `bootstrap.setup`, causing
a sys.modules collision that silently dropped test_telemetry_databases_exist
from integration's bootstrap. With no __init__.py anywhere, pytest treats
each setup.py as a standalone module via spec_from_file_location and both
are collected cleanly.

Updates tests/README.md, tests/e2e/README.md, and tests/e2e/CLAUDE.md path
references from e2e/src/bootstrap/ to e2e/bootstrap/.

* refactor(tests/e2e): drop specs/ + strip // spec: back-pointers

specs/ held markdown test plans that mirrored tests/ 1:1 as pre-code
scratch. Once a test exists, the plan is stale the moment the test
diverges — they're AI-planner output, not source of truth. Keep the
workflow alive by .gitignore-ing specs/ (the planner agent can still
write locally) but stop shipping stale plans in the repo.

Strip the `// spec: specs/...` and `// seed: tests/seed.spec.ts` header
comments from 5 .spec.ts files. The spec pointer is dead; the seed
pointer was convention-only — Playwright collects regardless.

* docs(contributing/tests): move e2e/integration guides out of test dirs

Pull the e2e contributor guide out of tests/e2e/CLAUDE.md (which read
like a full agent-workflow reference doc) and into
docs/contributing/tests/e2e.md alongside the existing development / go
guides.

- Delete tests/e2e/CLAUDE.md; its content (layout, commands, role tags,
  locator priority, Playwright agent workflow) lives in the new e2e.md
  with references to the now-.gitignore'd specs/ dir removed.
- Add docs/contributing/tests/integration.md — short guide covering
  layout, runner commands, filename conventions, and the flow for
  adding a new suite (there was no contributor doc for this before).
- Trim tests/e2e/README.md to quick-start + commands; link out to the
  full guide. Readers who just want to run tests get the 5 commands
  they need; anything deeper is one hop away.

* chore(tests/e2e): drop examples/example-test-plan.md

Init-agents boilerplate. Fresh planner agents don't need a checked-in
template; they can write to the .gitignore'd specs/ scratch dir.

tests/integration/.qodo/ was also removed (untracked, empty; .qodo is
already in the root .gitignore).

* refactor(tests/seeder): use fixtures.logger.setup_logger

Drop the one-off logging.basicConfig + logging.getLogger("seeder") in
favor of the shared setup_logger helper that every fixtures/*.py already
uses. Keeps log format consistent across pytest runs and the seeder
container.

fixtures.logger ships into the image via the existing COPY fixtures step
in Dockerfile.seeder — no build change needed.

* fix(tests/e2e): correct e2e_dir path after src/ flatten

After phase 2 (flatten tests/e2e/src/ into tests/e2e/), the run.py file
sits one level closer to the e2e root. parents[2] now resolves to tests/
instead of tests/e2e/, so yarn test would subprocess from the wrong cwd.

parents[1] is the correct index now.

* fix(tests/e2e): correct endpoint-file path in setup.py after src/ flatten

Same class of stale-path bug as the run.py fix: after the e2e/src/
flatten, setup.py sits one level closer to the e2e root. parents[2] now
lands at tests/ instead of tests/e2e/, so .signoz-backend.json would be
written to tests/.signoz-backend.json and the Playwright global.setup.ts
(which expects tests/e2e/.signoz-backend.json) wouldn't find it.

parents[1] is correct.

* refactor(tests/e2e): drop pre-seed fixtures; each spec owns its data

The seeder (tests/seeder/) was built so specs can POST telemetry
per-test. Global pre-seeding via tests/e2e/conftest.py (seed_dashboards,
seed_alert_rules, seed_e2e_telemetry) is the exact anti-pattern that
setup obsoletes — shared state across specs, order-dependent runs, no
reset between tests.

- Delete tests/e2e/conftest.py (3 fixtures, all pre-seed).
- Delete tests/e2e/testdata/dashboards/apm-metrics.json — its only
  consumer was seed_dashboards. tests/e2e/testdata/ now empty and gone.
- Drop seed_dashboards, seed_alert_rules, seed_e2e_telemetry params
  from bootstrap/setup.py::test_setup and bootstrap/run.py::test_e2e.
  test_teardown never depended on them.
- Refresh the module docstrings on both bootstrap tests to reflect the
  new model (backend + seeder up; specs seed themselves).
- Update tests/README.md and docs/contributing/tests/e2e.md: remove the
  testdata/ + conftest.py references, document the per-spec seeding
  rule (telemetry via seeder endpoints, dashboards/alerts via SigNoz
  REST API from the spec).

Known breakage: tests/e2e/tests/dashboards/dashboards-list.spec.ts
expects at least one dashboard to exist. With seed_dashboards gone, it
will fail until that spec is updated to create its own dashboard via
the SigNoz API in test.beforeAll. Followup.

* refactor(tests/e2e): relocate auth helper into fixtures/; expose authedPage

Rename tests/e2e/utils/login.util.ts → tests/e2e/fixtures/auth.ts and
drop the (now-empty) utils/ dir. "Fixtures" is the unit of per-test
shared setup on both the Python and TS sides of this project — naming
them consistently across trees makes the parallel obvious.

fixtures/auth.ts now exports three things:

- `test` — Playwright test extended with an authedPage fixture. New
  specs can request `authedPage` as a param and skip the
  `beforeEach(() => ensureLoggedIn(page))` boilerplate entirely.
- `expect` — re-exported from @playwright/test so callers have one
  import.
- `ensureLoggedIn(page)` — the underlying helper, still exported for
  specs that want per-call control.

Update the 4 specs that imported from utils/login.util to point at the
new path; no behavior change in those specs (they keep calling
ensureLoggedIn in beforeEach). Refactoring them to use authedPage can
happen spec-by-spec later.

Also update the path example in .cursorrules so AI-generated snippets
reach for the new import path.

* refactor(tests/e2e): emit .env.local instead of .signoz-backend.json

The old flow (pytest writes JSON → global.setup.ts loads it → exports
env vars) was doing what dotenv already does. Collapse to the native
pattern:

- bootstrap/setup.py writes tests/e2e/.env.local with the four coords
  (BASE_URL, USERNAME, PASSWORD, SEEDER_URL). File header marks it as
  generated.
- playwright.config.ts loads .env first, then .env.local with
  override=true. User-provided defaults stay in .env; generated values
  win when present.
- Delete tests/e2e/global.setup.ts (36 lines gone) and its globalSetup
  reference in playwright.config.ts.

Subprocess-injected env (run.py shelling out to yarn test) still wins
because dotenv doesn't overwrite already-set process.env keys.

Rename the test-only override env var SIGNOZ_E2E_ENDPOINT_FILE →
SIGNOZ_E2E_ENV_FILE for accuracy. Update .env.example, .gitignore (drop
.signoz-backend.json, keep .env.local with its explanatory comment),
tests/README.md, docs/contributing/tests/e2e.md.

* refactor(tests/e2e/alerts-downtime): drop custom network + screenshot capture

The spec wrapped every /api/ response in a bespoke installCapture(), wrote
hand-named JSON files per call (01_step1.1_GET_rules.json, ...), and took
step-by-step screenshots — all going into run-spec-<ts>/ next to the spec
(gitignored).

Playwright already records equivalent data via `trace` (network bodies,
screenshots per step, DOM snapshots, console — viewable via
`playwright show-trace`). The capture infra was duplicating that for the
one-shot 2095 regression audit; no downstream consumer reads the JSON or
PNG artifacts now.

- Remove installCapture, shot, RUN_DIR/NET_DIR/SHOT_DIR, fs/path imports.
- Strip cap.mark()/cap.dumpSince()/shot() calls throughout the 7 flows.
- Collapse the block-scopes that only existed to bound mark variables.
- Drop the "Artifacts" paragraph from the file's top-of-file comment.
- Remove the `tests/alerts-downtime/run-spec-*/` entry from .gitignore.

Spec drops from 885 lines to 736 (≈17% smaller). All 7 flows + their
assertions are unchanged. For debug access, rely on
`trace: 'on-first-retry'` (already set in playwright.config.ts) + `yarn
show-trace`.

* refactor(tests/e2e): move alerts-downtime.spec.ts into alerts/

The spec lives mostly in the alerts domain (6 of 7 flows), with the
planned-downtime CRUD (Flow 4) and cascade-delete (Flow 5) as
cross-feature collateral. The standalone alerts-downtime/ dir was
compound-named, breaking the one-feature-per-dir pattern every other
dir under tests/ follows, and duplicating the spec's own filename.

Move to tests/alerts/alerts-downtime.spec.ts. Empty alerts-downtime/
dir removed.

* refactor(tests/e2e): consolidate Playwright output under artifacts/

All Playwright outputs now land under a single tests/e2e/artifacts/ dir
so CI can archive it in one command (tar / zip / upload-artifact). Each
piece was writing to its own sibling of tests/e2e/ before.

playwright.config.ts:
- outputDir: 'artifacts/test-results' — per-test traces, screenshots,
  videos (was default test-results/).
- HTML reporter → 'artifacts/html-report' (was default
  playwright-report/); open: 'never' so CI doesn't spawn a browser on
  report generation.
- JSON reporter → 'artifacts/results.json' (was
  'test-results/results.json').

package.json: `yarn report` now points playwright show-report at the new
HTML folder.

Ignore updates — replace the two old paths with /artifacts/ in
tests/e2e/.gitignore, tests/e2e/.prettierignore, and tests/.dockerignore
(seeder image build context).

.cursorrules: update the `cat test-results/results.json` example to the
new path so AI-generated snippets reach for the right file.

Delete the empty test-results/ and playwright-report/ dirs that prior
runs left behind.

* refactor(tests/e2e): one artifacts/ subdir per reporter

Within artifacts/, give each reporter its own named subdir so the layout
tells you what wrote what:

  artifacts/
    html/              # HTML reporter (was artifacts/html-report)
    json/results.json  # JSON reporter (was artifacts/results.json)
    test-results/      # outputDir — per-test traces/screenshots/videos

`yarn report` and the .cursorrules cat example point at the new paths.

* refactor(tests/e2e): drop SIGNOZ_USER_ROLE env filter and @admin/@editor/@viewer tags

The filter claimed to be role-based but only grep'd by tag — the actual
browser session is always admin (bootstrap creates one admin, auth.setup.ts
saves one storageState, every project uses it). Tagging tests `@viewer`
didn't mean they ran as a viewer; it just meant they'd be in the subset
selected when SIGNOZ_USER_ROLE=Viewer. Superset semantics (admin sees
everything) meant the filter was at best a narrower test selection and
at worst a misleading assertion of role coverage.

Gone:
- getRoleGrepPattern() + grep: line in playwright.config.ts.
- The dedicated setup project's grep override (no filter to override).
- SIGNOZ_USER_ROLE entries in .env.example, README, docs/contributing.
- The "Role-Based Testing" section + all role-tagging guidance and
  example snippets in .cursorrules.
- All `{ tag: '@viewer' | '@editor' | '@admin' }` annotations on the 90
  affected test sites across 5 spec files (single-line and multi-line
  forms). ~90 annotations gone.

For ad-hoc selection, `yarn test --grep <pattern>` still works on
Playwright's normal grep (test titles/paths).

Real role-based coverage (separate users + storageStates per role) is a
different problem — not pretending this was it.

* chore(tests/e2e): drop .cursorrules

* refactor(tests/e2e): move auth from project-level storageState to per-suite fixture

Replaced auth.setup.ts + globally-mounted storageState with a test-scoped
authedPage fixture in tests/e2e/fixtures/auth.ts. Each suite controls its
own identity via `test.use({ user: ... })`; specs that need to run
unauthenticated just request the stock `page` fixture instead.

fixtures/auth.ts:
- Declares `user` as a test option, defaulting to ADMIN (creds from
  .env.local / .env).
- authedPage resolves to a Page whose context has storageState mounted
  for that user. First request per (user, worker) triggers one login
  and writes a per-user storageState file under .auth/; subsequent
  requests reuse it via a Promise-valued cache.
- Exposes `User` type and `ADMIN` constant so future suites can declare
  additional users (EDITOR, VIEWER) as credentials become available.

playwright.config.ts:
- Drop authFile constant, `setup` project, storageState + dependencies
  on each browser project.

tests/auth.setup.ts:
- Deleted. Login logic now lives inside fixtures/auth.ts's login() helper,
  called on demand by the fixture rather than upfront for the whole run.

Spec migration (6 files):
- Import `test, expect` from ../fixtures/auth (or ../../fixtures/auth)
  instead of @playwright/test.
- Drop `ensureLoggedIn` imports and `await ensureLoggedIn(page)` calls.
- Swap `{ page }` → `{ authedPage: page }` in test and beforeEach
  destructures (local var stays `page` via aliasing so test bodies need
  no further changes).

Cost: N logins per run, where N = unique users × workers (= 1 × 2–4
today, vs the old 1 globally). Tradeoff for explicit per-suite control.

Specs that need unauth later just use `async ({ page }) => ...` — the
fixture isn't invoked, so no login fires.

291 tests still list (previously 292: the old auth.setup.ts counted as
one fake "test"; it's gone now).

* refactor(tests/e2e): cache auth storageState in memory, drop .auth/ dir

The fixture was writing each user's storageState to .auth/<user>.json and
then handing Playwright the file path. But Playwright's
browser.newContext({ storageState }) accepts the object form too —
ctx.storageState() without a path arg returns the cookies+origins
inline.

Keeping the cache in memory means no filesystem roundtrip per login, no
.auth/ dir to maintain, no stale JSON persisting across runs, and no
gitignore entry for it. Each worker's Map holds one Promise<StorageState>
per unique user, resolved on first login and reused thereafter.

Drop the .auth/ entry from tests/e2e/.gitignore; delete the (now unused)
on-disk .auth/ dir.

* chore(tests/e2e): drop seed.spec.ts

* chore(tests/e2e): drop unused README.md and .mcp.json

* refactor(tests/e2e): move existing specs to legacy/ pending fresh rewrite

Park the 5 current spec files under tests/e2e/legacy/ while fresh specs
get written in tests/e2e/tests/ against the new conventions (TC-NN
titles, authedPage fixture, minimal direct-fetch). Playwright's testDir
stays pointed at ./tests — `yarn test` now finds 0 tests until the
first fresh spec lands. legacy/ is preserved for reference but not
collected by default.

Add a .gitkeep under tests/ so the empty dir survives in git between
the move and the first new spec.

Running legacy on demand:
  npx playwright test --config tests/e2e/playwright.config.ts \
    --project chromium legacy/<spec>.ts
(or temporarily point testDir at ./legacy in the config). No yarn
script wired — legacy is expected to rot as fresh specs replace it.

* refactor(tests): drop -utils deprecation shims; import from canonical modules

The shims we introduced during the phase-3 merges (authutils, alertutils,
cloudintegrationsutils, idputils, gatewayutils) and the phase-4 primitive
renames (dev, utils, driver) have done their job — integration/ tests can
now import directly from the real modules.

Rewrite every shim-import in tests/integration/tests/:
  fixtures.authutils → fixtures.auth
  fixtures.alertutils → fixtures.alerts
  fixtures.cloudintegrationsutils → fixtures.cloudintegrations
  fixtures.idputils → fixtures.idp
  fixtures.gatewayutils → fixtures.gateway
  fixtures.utils (get_testdata_file_path) → fixtures.fs

Delete all 8 shim files:
  fixtures/{authutils,alertutils,cloudintegrationsutils,idputils,
  gatewayutils,dev,utils,driver}.py

Nothing in active code (integration tests, e2e fixtures, bootstrap, seeder)
imported fixtures.dev or fixtures.driver, so those had no callers to
sweep — just delete.

500 tests still collect.

* fix(tests/seeder): add python3-dev so psycopg2 can compile in the image

Consolidating seeder deps into pyproject.toml pulled in psycopg2, which
needs Python dev headers (Python.h) to build from source. The apt layer
had gcc + libpq-dev but was missing python3-dev, so \`uv sync --frozen
--no-install-project --no-dev\` failed with "gcc failed with exit code 1"
during the seeder image build.

Add python3-dev to the apt install line; image size bump ~50MB for dev
headers. Alternative would have been swapping psycopg2 for
psycopg2-binary in pyproject.toml, but that'd affect the whole test
project for one Dockerfile concern — wrong scope.

* feat(tests/e2e): re-author 2095 alerts + downtime regression

Three fresh specs split by resource replace the 736-line
legacy monolith at tests/e2e/legacy/alerts/alerts-downtime.spec.ts:

- alerts.spec.ts: rule list CRUD, labels round-trip, test-notification
  pre-state, details/history/AlertNotFound, anomaly (EE-gated, skip on
  community)
- downtime.spec.ts: planned-downtime CRUD round-trip
- cascade-delete.spec.ts: 409 paths on rule/downtime delete when linked

UI-first: Playwright traces capture the BE conversations, so direct
page.request calls are reserved for seeding where the query-builder
setup is incidental to the test, API-contract probes, and cleanup.

* refactor(tests/e2e): group alerts specs under tests/alerts/

* feat(tests/fixtures/auth): apply_license fixture + wire into e2e bootstrap

- Adds a package-scoped apply_license fixture that stubs the Zeus
  /v2/licenses/me mock and POSTs /api/v3/licenses so the BE flips to
  ENTERPRISE. The fixture also PUTs org_onboarding=true because the
  license enables the onboarding flag which would otherwise hijack
  every post-login navigation to a questionnaire.
- Wires apply_license into e2e/bootstrap/setup.py::test_setup and
  ::test_teardown alongside create_user_admin.
- Existing add_license helper stays as-is for integration tests.
- Login fixture now waits for the URL to leave /login instead of a
  pre-license "Hello there" welcome string (the post-login landing
  page varies with license state).
- TC-07 anomaly test no longer skips (license enables the flag) and
  drops the legacy test-notification API contract probe that needs
  seeded metric data (covered by the integration suite).

* chore: cleanup

* chore: remove claude files

* chore(tests/fixtures): drop unused dashboards.py

* chore(tests/e2e): rename playwright outputDir to artifacts/results

* chore(tests/e2e): drop legacy specs, trim alerts.spec.ts to one smoke test

Deletes tests/e2e/legacy/ (five old 2095-replay specs) and the two
sibling alerts suite files (downtime, cascade-delete). alerts.spec.ts
is reduced to a single TC-01 smoke test that loads /alerts and asserts
the tabs render — a fresh minimum to build on.

* docs(contributing): new integration.md + e2e.md at top level

Promotes the two test-contributor docs from docs/contributing/tests/
to docs/contributing/ and rewrites them in the long-form Q&A format
of docs/contributing/go/integration.md (prerequisites → setup →
framework → writing → running → configuring → remember).

Reflects the current state: shared fixtures package at tests/fixtures/,
flat integration suites under tests/integration/tests/, e2e specs
grouped by resource under tests/e2e/tests/<feature>/, apply_license
fixture in the bootstrap, authedPage Playwright fixture, and the
artifacts/{html,json,results} output layout.

* docs(contributing): relocate integration.md + e2e.md to tests/

Moves docs/contributing/go/integration.md -> docs/contributing/tests/integration.md
and docs/contributing/e2e.md -> docs/contributing/tests/e2e.md so the test-
contributor docs live under contributing/tests/. The previous top-level
promotion at docs/contributing/integration.md is removed; go/readme.md
drops the dangling integration link.

* docs(contributing/tests): update integration.md to current repo layout

* ci(tests): fix integrationci paths + add e2eci workflow

integrationci:
- Matrix path was integration/src/<suite> (old layout); current layout
  is integration/tests/<suite>. Renames the matrix key src -> suite and
  fixes the pytest path accordingly.
- Adds auditquerier and rawexportdata to the matrix (new suites).
- Drops bootstrap from the matrix — it's no longer a test suite, just
  the pytest lifecycle entry.

e2eci (new, replaces the broken frontend/-based run-e2e.yaml):
- Label-gated trigger mirroring integrationci: requires safe-to-test +
  safe-to-e2e. Runs on pull_request / pull_request_target.
- Installs Python (uv) and Node (yarn), syncs tests/ deps, installs
  Playwright browsers for the matrix project.
- Brings the stack up via e2e/bootstrap/setup.py::test_setup --with-web
  (build signoz-with-web container once), runs playwright against it,
  tears down in an always-run step.
- Uploads the HTML report + per-test traces as artifacts.
- Matrix starts with chromium only (firefox / webkit can follow).

* ci(tests/e2e): upload entire artifacts/ dir, 5-day retention

* fix(tests/fixtures): apply black formatting to truncate helpers

* fix(tests/pyproject): ignore node_modules and py module in pylint

* ci(tests): drop auditquerier from integrationci matrix for now

* refactor(tests): drop __file__.parents[N] path tricks; use pytestconfig.rootpath

The pytest rootdir is already tests/, so anywhere we were computing
_REPO_ROOT / _TESTS_ROOT / e2e-dir from Path(__file__).resolve().parents[N]
can just use pytestconfig.rootpath (or .parent for the repo root).

- fixtures/signoz.py: DockerImage path → pytestconfig.rootpath.parent
- fixtures/seeder.py: docker-py build path → pytestconfig.rootpath
- e2e/bootstrap/setup.py: .env.local path → pytestconfig.rootpath / e2e
- e2e/bootstrap/run.py: yarn-test cwd → pytestconfig.rootpath / e2e

* chore(tests/e2e): drop bootstrap/run.py

The run.py entrypoint was just setup.py + subprocess('yarn test'); CI
splits those steps anyway (separate provision / test / teardown for
clean artifact capture) and locally the two-step flow is equivalent.
Removing the duplicate entrypoint; docs updated accordingly.

* cleanup(tests): simplify review pass

- fixtures/fs.py: testdata path resolved to tests/testdata after the
  fixture move; integration tests with data-driven parametrize (e.g.
  alerts/02_basic_alert_conditions.py) were all failing with
  FileNotFoundError. Walk to tests/integration/testdata now.
- fixtures/auth.py: extract _login helper so apply_license stops
  duplicating the GET /sessions/context + POST /sessions/email_password
  pair. Add a retry loop on POST /api/v3/licenses so a BE that isn't
  quite ready at bring-up time doesn't fail the fixture.
- seeder/server.py: use FastAPI lifespan to open+close the ClickHouse
  client instead of a lazy module-level global; collapse the verbose
  module docstring.
- fixtures/seeder.py + e2e/bootstrap/setup.py: trim docstrings/comments
  that narrated WHAT the code does — per-repo convention keeps only
  non-obvious WHY.
- .github/workflows/integrationci.yaml: gate the Chrome + chromedriver
  install on matrix.suite == 'callbackauthn' (the only suite that uses
  Selenium). Saves ~30s × 50 jobs on every PR run.
2026-04-23 10:05:49 +00:00
Vikrant GuptaandGitHub 484b22c12a chore(codeowner): add @therealpandey as codeowner (#11055) 2026-04-22 09:51:02 +00:00
PandeyandGitHub 52992c0e80 chore(switch): switch for some time to @therealpandey (#11017) 2026-04-20 13:29:03 +00:00
Vikrant GuptaandGitHub d677973d56 test(integration): add test cases for new user APIs (#10837)
* test(integration): add user_v2 tests

* test(integration): fix fmt

* test(integration): disable delete mode from tests

* test(integration): add response.text when the assertion fails

* test(integration): some renaming
2026-04-04 14:43:55 +00:00
Vikrant GuptaandGitHub 13249b5e69 feat(sqlstore): enable wal mode by default (#10822)
* chore(sqlstore): run integration tests on wal and immediate

* chore(sqlstore): remove the txlock changes

* chore(sqlstore): make wal the default mode
2026-04-03 15:48:37 +00:00
bad80399a6 feat(serviceaccount): integrate service account (#10681)
* feat(serviceaccount): integrate service account

* feat(serviceaccount): integrate service account with better types

* feat(serviceaccount): fix lint and testing changes

* feat(serviceaccount): update integration tests

* feat(serviceaccount): fix formatting

* feat(serviceaccount): fix openapi spec

* feat(serviceaccount): update txlock to immediate to avoid busy snapshot errors

* feat(serviceaccount): add restrictions for factor_api_key

* feat(serviceaccount): add restrictions for factor_api_key

* feat: enabled service account and deprecated API Keys (#10715)

* feat: enabled service account and deprecated API Keys

* feat: deprecated API Keys

* feat: service account spec updates and role management changes

* feat: updated the error component for roles management

* feat: updated test case

* feat: updated the error component and added retries

* feat: refactored code and added retry to happend 3 times total

* feat: fixed feedbacks and added test case

* feat: refactored code and removed retry

* feat: updated the test cases

---------

Co-authored-by: SagarRajput-7 <162284829+SagarRajput-7@users.noreply.github.com>
2026-04-01 07:20:59 +00:00
bb4e7df68b chore: add rule state history module (#10488)
* chore: add rule state history module

* chore: run generate

* chore: generate

* Fix timeline default limit and escape exists key (#10490)

Co-authored-by: Cursor Agent <cursoragent@cursor.com>

* chore: remove unused AddRuleStateHistory and add comments

* chore: regenerate

* chore: update names and move functions

* chore: remove return

* chore: update .github/CODEOWNERS for history

* chore: update condition builder

* chore: lint

---------

Co-authored-by: Cursor Agent <cursoragent@cursor.com>
2026-03-30 10:38:52 +00:00
Hanzo Dev ea3f0b47b7 fix: add pnpm-lock.yaml + update CI workflows (yarn → pnpm) 2026-03-25 13:29:55 -07:00
Hanzo Dev b51a41ab4e ci: enable multi-arch builds (amd64 + arm64 native runners) 2026-03-24 22:47:26 -07:00
Hanzo Dev f7ef801bf1 ci: migrate Docker build to shared reusable workflow
Add multi-stage root Dockerfile (frontend + Go build + alpine
runtime) so the shared workflow can build everything in one
docker build. Replace the old build-ghcr.yaml (pre-build
outside Docker + thin COPY image) with a single call to
hanzoai/.github/.github/workflows/docker-build.yml@main.

amd64-only until arm64 runner is restored.
2026-03-24 22:32:55 -07:00
Hanzo Dev 2ae8d521a6 ci: add multi-env Docker image tagging for test/dev branches
Replace rebrand/hanzo-o11y branch trigger with test and dev. Existing
metadata-action tags (type=ref,event=branch) produce :test and :dev
image tags automatically.
2026-03-24 20:55:40 -07:00
Hanzo Dev 24760d7031 fix: update frontend yarn.lock for frozen-lockfile CI compatibility
yarn.lock was out of date after package.json changes in rebrand commits.
CI builds with --frozen-lockfile were failing. Also remove deprecated
build-community.yaml and build-enterprise.yaml workflows.
2026-03-24 20:09:11 -07:00
PandeyandGitHub dfe2a6a9e5 fix(tests): fix flaky rootuser integration tests (#10660)
* fix(tests): fix flaky rootuser integration tests

setupCompleted becomes true before the root user is actually created
because the reconciliation runs in an async goroutine. Add a second
polling phase that waits for /api/v1/user to return 200, confirming
the root user exists and the impersonation provider can resolve.

* fix(ci): fail py-fmt check when formatter changes files

Add git diff --exit-code after make py-fmt so CI fails if any files
are not properly formatted, instead of silently passing.

Also includes black formatting fix for 01_rootuser.py.

* refactor(tests): remove redundant unauthenticated request test

test_unauthenticated_request_succeeds is redundant now that
test_root_user_created already polls /api/v1/user without auth
and waits for 200.
2026-03-19 20:22:02 +00:00
PandeyandGitHub ca9cbd92e4 feat(identn): implement an impersonation identn (#10641)
* feat(identn): implement an impersonation identn

* fix: prevent nil pointer error

* feat: dry org code by implementing getbyidorname

* feat: add integration tests for root user and impersonation

* fix: fix lint
2026-03-19 10:13:12 +00:00
PandeyandGitHub 2db83b453d refactor: merge roletypes into authtypes (#10614)
* refactor: merge roletypes into authtypes

* refactor: merge roletypes into authtypes

* refactor: update openapi spec

* feat: split CI

* fix: fix tsc of frontend
2026-03-17 15:43:58 +00:00
Vikrant GuptaandGitHub aa05a7bf14 chore(identn): add me as codeowner for identn (#10612) 2026-03-17 11:29:34 +00:00
PandeyandGitHub cab4a56694 chore: add myself as codeowner for CI and go.mod (#10597)
Clarified CODEOWNERS comments and updated owner assignments.
2026-03-16 10:01:36 +00:00
Ashwin BhatkalandGitHub 78041fe457 chore: send slack notification on dequeue only and not merge (#10596) 2026-03-16 09:38:04 +00:00
Ashwin BhatkalandGitHub 9689b847f0 chore: add slack notification on dequeue from merge queue (#10580)
* chore: add slack notification on merge queue failure

* chore: break type

* chore: update yaml

* chore: update yaml

* chore: update yaml

* chore: update yaml

* chore: update yaml

* chore: update yaml

* chore: update yaml

* chore: resolve comments
2026-03-16 07:12:19 +00:00
Hanzo Dev 76354e07ef rebrand: purge posthog, clickhouse, signoz from frontend
- posthog-js → @hanzo/insights, all variable names posthog → insights
- POSTHOG_KEY → INSIGHTS_KEY across env, vite config, CI workflow
- clickhouse → datastore: types, enums, components, directories (386 occurrences)
- ChQuerySection → DsQuerySection directory and component rename
- signoz → o11y/hanzo in all onboarding docs, URLs, brand text
- X-SIGNOZ-QUERY-ID → X-O11Y-QUERY-ID header
2026-03-13 12:16:06 -07:00
Ashwin BhatkalandGitHub 4b4ef5ce58 fix: edit mode variables not persisting value (#10576)
* fix: edit mode variables not persisting value

* chore: move into hook

* chore: add tests

* chore: fix tests

* chore: move functions
2026-03-13 07:49:40 +00:00
Hanzo Dev d4c37deda9 fix(ci): bump node to 22, go to 1.25, fix community binary name
- Frontend requires Node >= 22.0.0
- go.mod requires go >= 1.25.0
- Community Dockerfile expects o11y-community binary, not signoz
2026-03-12 02:13:42 -07:00
Hanzo Dev 44a947bd32 ci: add GHCR build workflow for o11y Docker images 2026-03-12 02:10:29 -07:00