PR #7992 converted four of the five `err instanceof FormbricksHub.APIError`
checks to `getErrorStatus(err)` and removed the `FormbricksHub` default
import, but left the inline check in `deleteFeedbackRecord`. Since the
import is gone, the orphan reference throws ReferenceError at runtime
(visible in SonarCloud's coverage run on `vitest run --coverage`).
Completes the conversion so all catch handlers use the duck-typed helper.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Remove sentiment, emotion, and the TopicsUnnested join from the Cube
schema, web registry, AI prompt, audit-allowlist, and i18n keys — these
required metadata enrichment that is no longer planned. Tests swap the
removed string dimensions for sourceType to keep coverage intact.
Add csatDissatisfiedCount and csatNeutralCount so dashboards can render
the standard satisfied/neutral/dissatisfied distribution alongside the
existing top-2-box metric.
Expose field_label, field_group_label, language, value_boolean,
value_date, created_at, and updated_at as Cube dimensions. fieldLabel
and fieldGroupLabel unlock "group by question" and the matrix/ranking
aggregations enabled by the recent composite-question PR; the others
round out coverage of the underlying feedback_records columns. Extend
FieldDefinition with a boolean type and matching filter operators.
- Drop the prisma.$transaction wrapper; find + delete is two sequential
steps, doesn't need a transaction.
- Drop the redundant ResourceNotFoundError catch branch; the trailing
`throw error` already lets it bubble.
- Let action-client infer ctx / parsedInput types.
Tests: cover the two catch branches (Prisma -> DatabaseError, unknown
rethrow) so the new function is fully line-covered.
Adds CSAT and CES measures, plus a couple of universal cross-type measures,
to the FeedbackRecords Cube. Also fixes correctness bugs in the existing NPS
measures and constrains the AI chart-query output to known measure / dimension
ids.
Measures added
- csatScore: % of answered CSAT responses rated 4 or 5 (top-2-box on 1-5).
- csatAverage: AVG of answered CSAT ratings.
- csatSatisfiedCount: count where field_type='csat' AND value_number >= 4.
- csatCount: count of answered CSAT responses.
- cesAverage: AVG of answered CES ratings (1-5 or 1-7 depending on the question).
- cesCount: count of answered CES responses.
- uniqueRespondents: countDistinct(user_id).
- uniqueResponses: countDistinct(submission_id).
- npsAverage: AVG of answered NPS ratings (replaces the old `averageScore`
measure, which silently averaged every numeric value across all field types).
Bug fixes (existing NPS measures)
- promoterCount / passiveCount / detractorCount / npsScore now filter
field_type = 'nps'. Before, any numeric value in the band was counted
(so a CSAT 5/5 was lumped in as a detractor).
- npsScore now divides by *answered* NPS responses only (value_number IS NOT
NULL); dismissed/abandoned NPS records no longer drag the score toward 0.
- npsScore returns NULL when no answered NPS responses exist instead of the
literal 0, so empty-data days render as gaps rather than a misleading
flat-zero line.
- Same NULL-safe denominator fix applied to csatScore.
- csatCount / cesCount now exclude dismissed (value_number IS NULL) responses
so they match the score denominators.
Dimensions
- Renamed `npsValue` -> `valueNumber` (the underlying value_number column
stores values for NPS, CSAT, CES, rating, and number field types).
- New `valueText` dimension for grouping by categorical / open-text answers.
AI chart generation
- ZGenerateAIQueryResponse now enum-constrains `measures`, `dimensions`,
`timeDimensions.dimension`, and `filters.member` against the known ids
derived from FEEDBACK_FIELDS. Vercel AI SDK + Gemini structured outputs
enforce these at decoding time, so the model can no longer return invalid
or hallucinated measure names.
- generateText now pins temperature: 0. Same prompt produces the same query.
Breaking changes
- Charts that referenced `FeedbackRecords.averageScore` need to switch to
`FeedbackRecords.npsAverage`.
- Charts that referenced `FeedbackRecords.npsValue` need to switch to
`FeedbackRecords.valueNumber`.
Pre-GA on epic/v5; no production charts are expected to be impacted yet.
ENG-901: clicking Remove on a chart widget no longer enters dashboard edit mode
(which surfaced the rename input) and saving with the last widget removed no longer
surfaces a raw "widgets: Too small" zod error. Out of edit mode, Remove now goes
through a DeleteDialog -> dedicated removeWidgetFromDashboardAction. The batched
update path also allows an empty widgets array now that the lib already supports
deleting all widgets correctly.
ENG-903: add p-1 to AddExistingChartsDialog DialogBody so the focus ring on the
inner search input is no longer clipped by the body's overflow boundary.
Same pattern as CartesianChart's ChartTooltipRow — a module-level
component that calls useTranslation internally, plus a thin formatter
function passed to ChartTooltipContent. Resolves the nested-component
warning.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Switch from the native browser tooltip to the in-app inline error pattern:
red Label, isInvalid Input border, and helper text below the field. The
onInvalid handler suppresses the default tooltip and scrolls + focuses the
field via event.currentTarget — no ref needed. Typing clears the error.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Browsers default to "Please fill in this field"; use the existing
workspace.analysis.charts.please_enter_chart_name key so the message
matches the toast we surface elsewhere. Clear custom validity on change
so the form unblocks once the user types.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Replace the imperative scrollIntoView + focus on Save click with a tiny
<form> wrapping the required Input. The Save button becomes type=submit
with form="create-chart-form", so the browser handles scroll, focus, and
the "Please fill in this field" tooltip natively when the name is empty.
ChartDialogFooter now accepts either onSaveClick (button mode) or formId
(submit-button mode). All sibling buttons in the footer are explicitly
type="button" so they don't accidentally submit the form.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Clicking Save Chart with the name field empty fired a toast but left the
modal scrolled wherever the user was (e.g. on the chart preview at the
bottom), so they couldn't see what was wrong. Scroll the name field into
view and focus it before delegating to the existing save handler.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
The fractional-tick bar/line/area scenario isn't the bug we're shipping in
this PR. Keep only the pie tooltip spacing/formatting change.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Returning [value, name] from the tooltip formatter rendered as two adjacent text nodes ("3Nps"). Return a fragment with an explicit space so it reads "3 Nps".
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
ENG-914
When a chart's measures are all whole numbers (e.g. COUNT grouped by a
dimension), Recharts was auto-generating fractional y-axis ticks like
0.5, 1.5, 2 — nonsensical for a discrete count. The pie tooltip also
rendered values via raw String() with no thousand separators.
- Add allValuesAreIntegers() + formatYAxisTick() to chart-utils.
- CartesianChart now passes allowDecimals={false} and a number-aware
tickFormatter to YAxis when every measure value is an integer.
- ChartRenderer's pie tooltip routes the value through formatCellValue,
matching the Cartesian tooltip behaviour.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
- FormError ignored its children when an error was set, rendering the raw
zod message instead of the translated text passed in. Prefer explicit
children, fall back to the field error message.
- Use .at(-1) in getTranslatedFeedbackDirectoryError per SonarQube S7755.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Per Johannes on ENG-893: zero-workspace creation is acceptable — admins
move workspaces between directories and forcing at least one is an
arbitrary limitation. The unformatted-error fix
(getTranslatedFeedbackDirectoryError prefix stripping) is retained.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
ENG-893
Why: A feedback directory with zero workspaces is useless — it groups
nothing. The create path allowed it, and any validation error that did
fire surfaced as a raw "field: CODE" string in the toast.
How:
- createFeedbackDirectory now rejects empty/missing workspaceIds with
DIRECTORY_WORKSPACES_REQUIRED before touching the database.
- getTranslatedFeedbackDirectoryError strips the "<field>: " prefix that
next-safe-action prepends to validation errors, so machine codes always
map to a translated message.
- Add the new translation key across all 15 locales.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Tests now expect validation failures when CUBEJS_API_URL, CUBEJS_API_SECRET,
or HUB_API_KEY are missing, and all test env helpers provide HUB_API_KEY.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Makes Cube env vars mandatory in env.ts (per PR #7913) and adds them
as Docker build secrets with fallback values, following the same pattern
as DATABASE_URL, REDIS_URL, and HUB_API_URL.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
HUB_API_URL is required by the Zod env validation at build time but was
not provided as a Docker secret, causing the release build to fail.
Adds HUB_API_URL with a dummy fallback (http://localhost:4000) to the
build pipeline, following the same pattern as DATABASE_URL/REDIS_URL.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Hub 0.3.0 renames the `user_identifier` API field to `user_id` (breaking
change). This commit bumps the Hub Docker image, upgrades the
@formbricks/hub TypeScript SDK from 0.4.3 to 0.5.0, and renames every
`user_identifier` reference in Zod schemas, server actions, transform
pipeline, form components, CubeJS schema, connector types, and seed data
to match the new API contract.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Move duplicated function to @/lib/ai/service and export TAIUnavailableReason
type. Remove local copies from charts-list-page and dashboard-detail-page.
- Server-side: Replace hardcoded OpenAI with provider-agnostic `getAiModel(env)` and enforce
`assertOrganizationAIConfigured(organizationId, "dataAnalysis")` which validates license
entitlement, org-level toggle, and instance configuration
- Client-side: Instead of hiding AI section when unavailable, show it disabled with a tooltip
explaining the reason (not in plan / not enabled / instance not configured), following the
same pattern as AI translate
- Thread `isAIAvailable` and `aiUnavailableReason` through the component chain from server
pages down to `AIQuerySection`
- Update test mocks to match new provider-agnostic AI imports
The feedback-sources page was still using the old WorkspaceConfigNavigation
(secondary tabs) instead of the new unified settings sidebar introduced in
#7904. This caused an inconsistent navigation experience.
Changes:
- Create new route at /settings/workspace/feedback-sources
- Add feedback-sources entry to SettingsSidebarContent
- Remove old WorkspaceConfigNavigation from ConnectorsSection
- Redirect old /feedback-sources route to new settings path
- Update all stale /feedback-sources links across the codebase
All internal links (billing, enterprise, general, api-keys, feedback-record-directories,
integrations) now point to their correct nested paths under /settings/organization/ or
/settings/workspace/. Also adds feedback-record-directories to the new sidebar nav with
the member visibility rule.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Remove isBilling from WorkspaceBreadcrumb/WorkspaceAndOrgSwitch prop chain
- Remove unused common.organization_settings and common.unify translation keys
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
The tests were waiting for a redirect to app-connection that no longer
exists — user-actions is now a standalone page.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Replace individual settings items in workspace/org dropdowns with single Settings link
- Change Connect Your App icon from ListChecksIcon to UnplugIcon
- Remove unused code (isActiveOrganizationSetting, isActiveWorkspaceSetting, etc.)
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- action.spec.ts: navigate to user-actions page instead of app-connection
- organization.spec.ts: use level:1 to disambiguate "Teams" heading
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Restore settings sidebar in MainNavigation (lost during epic/v5 merge)
- Rename "Configuration" to "Settings", "Look & Feel" to "Appearance", etc.
- Fix SonarQube issues: duplicate class, regex injection, nested ternary, inline arrow functions
- Extract User Actions from Connect Your App into its own settings page
- Update all i18n translation keys across locales
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Disable all workspace and select org settings items for billing-role users
- Hide the top bar (back button) for billing users in settings mode
- Add organization switcher with lazy-loaded org list to landing sidebar
- Pass isMultiOrgEnabled to landing sidebar for create-org option
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Added Tooltip and Popover components to provide user feedback for disabled navigation items.
- Implemented conditional rendering of tooltips and popovers based on item state.
- Introduced a disabledMessage prop to display appropriate messages for unauthorized actions.
- Resolve merge conflict in create-connector-modal (keep NoFeedbackRecordDirectoryAlert)
- Fix GoBackButton URLs in slack, google-sheets, airtable integration pages to use /settings/workspace/integrations path
- Fix connectHref values in integrations page (webhooks, google-sheets, airtable, slack, notion, JS SDK)
- Fix handleWorkspaceChange to stay in settings mode when switching workspace from settings sidebar
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
The settings sidebar replaces the main nav, so the "Surveys" link is
not visible when on a settings page. Use direct URL navigation instead.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Consolidate all settings (Account, Organization, Workspace) under a unified
URL structure with a shared sidebar that replaces the main navigation when
in settings mode. Remove horizontal nav bars, old dropdown-based navigation
patterns, and route group layouts in favor of real URL segments.
- Move workspace settings from /(workspace)/ to /settings/workspace/
- Move org settings from /settings/(organization)/ to /settings/organization/
- Move account settings from /settings/(account)/ to /settings/account/
- Add SettingsSidebarContent with inline workspace/org switchers
- Replace main sidebar with settings nav when pathname includes /settings
- Update all page headings to match sidebar nav labels
- Update e2e tests for new URL structure and navigation patterns
- Remove unused translation keys
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Pipeline errors (snapshot loading or dispatch) should not prevent the
201 response from being returned. Dispatch pipeline events without
awaiting so the response is returned immediately.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Add optional chaining for organization.billing in response pipeline
- Add missing feedbackRecordDirectoryId to Chart seed data
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
The dropdown actions say "Enable"/"Disable" but the status badges showed
"In Progress"/"Paused". Now both use "Enabled"/"Disabled" for consistency.
Resolves ENG-769
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
The `?` operator only checks key existence — if the form layer saved
`{"elementHeadlineColor": null}` (JSON null = "use default"), the
migration skipped the copy and then removed the legacy key, losing
the color value. Switch to COALESCE(styling->'field', 'null'::jsonb)
= 'null'::jsonb which catches both missing keys (SQL NULL) and JSON
null values.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Ensures the UPDATE only processes JSONB objects, preventing errors
on unexpected scalar or array values in the styling column.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Aligns storybook story helpers and element stories with the legacy
field removal — inputColor → inputTextColor, mapping to
--fb-input-text-color CSS variable.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Replace the async job queue + Redis polling pattern with a direct
server action call. The translation now runs synchronously inside
translateSurveyFieldsAction, removing the need for BullMQ job
definitions, processors, cache keys, and client-side polling logic.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Replace remaining environment wording with workspace terminology across setup flows, API key permissions, and email preview text, and switch the email Tailwind config to ESM so formatting hooks run under the current Node runtime.
Made-with: Cursor
- Reuse ZAITranslationField from @formbricks/jobs instead of duplicating
the schema locally in actions.ts; tighten sourceLanguage/targetLanguage
validators with .min(1) to match the downstream job schema
- Guard against undefined translations in getAITranslationResultAction
instead of using the unsafe `translations!` assertion — return
"pending" status for malformed cache entries
- Use createCacheKey.custom("ai-translation", jobId) instead of raw
template strings to follow cache key conventions
- Improve JSON parsing robustness: strip markdown code fences before
attempting JSON.parse, log raw response on parse failures
- Add stale-request guard and error handling to the AI availability
useEffect in language-view.tsx
- Replace shared pollingCancelledRef boolean with per-invocation Symbol
token to prevent stale polling loops from clobbering state when the
modal is reopened
- Track timeout explicitly with a timedOut flag so the "timed out" toast
doesn't fire when polling was actually cancelled
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Add userId verification in getAITranslationResultAction (security)
- Use OperationNotAllowedError for auth failures
- Store failure marker in cache on last BullMQ attempt
- Make JSON parsing more robust (extract first {...} block)
- Add "keep modal open" hint to translating toast
- Add test coverage for process-ai-translation-job
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Resolve merge conflicts to combine AI translation and survey scheduling
features in jobs package, instrumentation, and tests.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Add a "Translate with AI" button to the Manage Translations modal that
auto-populates empty translation fields using the configured AI provider.
Translation runs as a BullMQ background job with results cached in Redis
and polled by the client.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Fix broken API URLs in docs-feedback.mdx (remove /workspaces segment, fix https://, remove stray };)
- Add missing workspaceId path params to v2 spec (responses, displays, user)
- Remove environmentId from required arrays in v2 request schemas
- Fix stale terminology: environment→workspace in database-model, tenant-separation, tags, actions
- Fix broken link to removed test-environment page in webhooks.mdx
- Fix redundant "codebase" in naming-conventions description
- Use neutral hostname in audit-logging example
- Hyphenate "open-source" in license.mdx
- Consistent workspaceId formatting in wordpress.mdx
- Update link text to match anchor in actions.mdx
- Remove dual environmentId/workspaceId in headless-surveys example
- Fix stale <project_id> placeholder in headless-surveys
- Fix awkward Next.js card copy in framework-guides.mdx
- Clarify BC wording in v2 introduction.mdx
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Replace invalid fake hex values (e.g. "#btn-bg", "#headline-color") with
valid hex colors so isLight() and mixColor() don't throw. Add missing
inputTextColor to the survey styling test so --fb-placeholder-color is set.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Add a SQL migration that copies legacy coarse-grained styling fields
to granular equivalents (e.g. questionColor → elementHeadlineColor,
inputColor → inputBgColor) and strips the legacy keys from the JSONB.
Remove the runtime deriveNewFieldsFromLegacy() shim, all fallback
chains in CSS variable generation, and update types, schemas, tests,
and OpenAPI spec to reflect the new canonical field names.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
message:`Language '${normalizedRequestedLanguage}' is ambiguous for this survey; use one of ${matchingLanguages.map((language)=>language.code).join(", ")}`,
};
}
constlanguageMatch=matchingLanguages[0];
if(languageMatch){
return{ok: true,code: languageMatch.code};
}
return{
ok: false,
reason:"unknown",
message:`Language '${normalizedRequestedLanguage}' is not configured for this survey`,
# V3 API — Surveys (hand-maintained; not generated by generate-api-specs).
# Implementation: apps/web/app/api/v3/surveys/route.ts and apps/web/app/api/v3/surveys/[surveyId]/route.ts
# See apps/web/app/api/v3/README.md and docs/Survey-Server-Actions.md (Part III) for full context.
openapi:3.1.0
info:
title:Formbricks API v3
description:|
**GET /api/v3/surveys** and **DELETE /api/v3/surveys/{surveyId}** — authenticate with **session cookie** or **`x-api-key`** (management key with access to the workspace).
**GET /api/v3/surveys**, **GET /api/v3/surveys/{surveyId}**, and **DELETE /api/v3/surveys/{surveyId}** — authenticate with **session cookie** or **`x-api-key`** (management key with access to the workspace).
**Spec location:** `docs/api-v3-reference/openapi.yml` (alongside v2 at `docs/api-v2-reference/openapi.yml`).
@@ -34,7 +33,7 @@ info:
The v3-backed survey overview page intentionally removes actions that are not yet exposed by this contract: `Created by` filtering, `Duplicate`, `Copy...`, `Preview`, and `Copy link`.
**Next steps (out of scope for this spec)**
Additional v3 survey endpoints, optional ETag/304, field selection — see Survey-Server-Actions.md Part III.
Additional v3 survey write endpoints, optional ETag/304, field selection, and survey version history.
version:0.1.0
x-implementation-notes:
route:apps/web/app/api/v3/surveys/route.ts
@@ -198,6 +197,174 @@ paths:
- sessionAuth:[]
- apiKeyAuth:[]
/api/v3/surveys/{surveyId}:
get:
operationId:getSurveyV3
summary:Retrieve a survey
description:|
Returns the public v3 survey management resource for one survey. By default, translatable
fields are returned as canonical multilingual maps keyed by real locale codes. Use `lang`
to filter those maps to one or more requested locale codes.
tags:
- V3 Surveys
parameters:
- in:path
name:surveyId
required:true
schema:
type:string
format:cuid2
description:Survey identifier.
- in:query
name:lang
required:false
style:form
explode:false
schema:
type:array
items:
type:string
examples:
- [de-DE]
- [de-DE, pt-PT]
description:|
Comma-separated locale code filter for translatable fields, for example `?lang=de-DE,pt-PT`.
The response shape stays stable: translatable fields are always maps keyed by locale code, never
strings. The parser is case-insensitive, accepts `_` or `-` separators, and normalizes to canonical
BCP 47 casing (`de_DE`, `DE-de` → `de-DE`). A language-only selector (`de`) resolves to the matching
configured survey language when exactly one exists; otherwise it returns `400`. Disabled-but-configured
languages are readable in the management API so unfinished translations can be completed. Aliases are
not accepted.
responses:
"200":
description:Survey retrieved successfully
headers:
X-Request-Id:
schema:{type:string }
description:Request correlation ID
Cache-Control:
schema:{type:string }
example:"private, no-store"
content:
application/json:
schema:
type:object
required:[data]
properties:
data:
$ref:"#/components/schemas/SurveyResource"
examples:
canonical:
summary:Canonical multilingual authoring resource
value:
data:
id:clseedsurveycsat000000
workspaceId:clseedworkspace000000000
createdAt:"2026-05-18T09:24:54.014Z"
updatedAt:"2026-05-18T09:24:54.014Z"
name:CSAT Survey
type:link
status:inProgress
metadata:{}
defaultLanguage:en-US
languages:
- code:en-US
default:true
enabled:true
- code:de-DE
default:false
enabled:false
welcomeCard:
enabled:false
blocks:
- id:e0tfwzqk63op37y14z95qq3k
name:Main Block
elements:
- id:nzte4cm8836hgjw63pesziht
type:rating
range:5
scale:smiley
headline:
en-US:How satisfied are you with our product?
de-DE:Wie zufrieden sind Sie mit unserem Produkt?
required:true
endings:[]
hiddenFields:
enabled:false
variables:[]
filtered:
summary:Language-filtered projection with ?lang=de-DE
description:Real locale code for the survey default language. The internal `default` translation key is never exposed.
languages:
type:array
items:
$ref:"#/components/schemas/SurveyLanguage"
welcomeCard:
$ref:"#/components/schemas/SurveyWelcomeCard"
blocks:
type:array
items:
$ref:"#/components/schemas/SurveyBlock"
endings:
type:array
items:
$ref:"#/components/schemas/SurveyEnding"
hiddenFields:
$ref:"#/components/schemas/SurveyHiddenFields"
variables:
type:array
items:
$ref:"#/components/schemas/SurveyVariable"
Problem:
type:object
description:RFC 9457 Problem Details for HTTP APIs (`application/problem+json`). Responses typically include a machine-readable `code` field alongside `title`, `status`, `detail`, and `requestId`.
Reference in New Issue
Block a user
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.