mirror of
https://github.com/snapotter-hq/SnapOtter.git
synced 2026-08-03 07:46:42 +02:00
feat: add usage onboarding survey overlay (#388)
* feat: add usage-survey feedback types and gating function Claude-Session: https://claude.ai/code/session_01KAC9Lbx8AmebAnj9WQZXHp * feat: add onboarding usage-survey i18n strings to all locales Relabels three ambiguous feedback.usageTypes values (personal/team_internal/ business_workflow) and adds a new onboarding namespace (4 keys) across the reference locale and all 20 translations, so the tree compiles at every commit instead of only after both locale groups land. Claude-Session: https://claude.ai/code/session_01KAC9Lbx8AmebAnj9WQZXHp * feat: add UsageSurveyOverlay component * feat: mount UsageSurveyOverlay inside AuthGuard Claude-Session: https://claude.ai/code/session_01KAC9Lbx8AmebAnj9WQZXHp * fix: use text-start instead of text-left for RTL support in UsageSurveyOverlay * refactor: drop redundant usage-type field from the admin feedback dialog Claude-Session: https://claude.ai/code/session_01KAC9Lbx8AmebAnj9WQZXHp * feat: accept onboarding source and survey id in the feedback route Claude-Session: https://claude.ai/code/session_01KAC9Lbx8AmebAnj9WQZXHp * test: cover the onboarding source in the feedback route integration test Claude-Session: https://claude.ai/code/session_01KAC9Lbx8AmebAnj9WQZXHp * chore: remove orphaned usageTypeLabel i18n key * refactor: derive feedback source/survey_id enums from a single source of truth * perf: skip the settings fetch in UsageSurveyOverlay for non-admin users
This commit is contained in:
@@ -7,14 +7,27 @@ import { analyticsEnabled, bakedEnabled } from "./analytics-gate.js";
|
||||
|
||||
let posthogClient: PostHog | null = null;
|
||||
|
||||
export const FEEDBACK_SOURCE_VALUES = [
|
||||
"global",
|
||||
"tool_result",
|
||||
"failed_job",
|
||||
"admin_installer",
|
||||
"search_miss",
|
||||
"onboarding",
|
||||
] as const;
|
||||
|
||||
export const FEEDBACK_SURVEY_ID_VALUES = [
|
||||
"global-feedback-v1",
|
||||
"tool-result-v1",
|
||||
"failed-job-v1",
|
||||
"admin-install-v1",
|
||||
"search-miss-v1",
|
||||
"onboarding-usage-v1",
|
||||
] as const;
|
||||
|
||||
export interface FeedbackEventProperties {
|
||||
source: "global" | "tool_result" | "failed_job" | "admin_installer" | "search_miss";
|
||||
survey_id?:
|
||||
| "global-feedback-v1"
|
||||
| "tool-result-v1"
|
||||
| "failed-job-v1"
|
||||
| "admin-install-v1"
|
||||
| "search-miss-v1";
|
||||
source: (typeof FEEDBACK_SOURCE_VALUES)[number];
|
||||
survey_id?: (typeof FEEDBACK_SURVEY_ID_VALUES)[number];
|
||||
prompt_variant?: string;
|
||||
sentiment?: "great" | "okay" | "issue" | "missing" | "bug" | "idea" | "other";
|
||||
feedback_type?: "bug" | "feature_request" | "confusing_ux" | "performance" | "other";
|
||||
|
||||
@@ -1,23 +1,14 @@
|
||||
import type { FastifyInstance, FastifyReply, FastifyRequest } from "fastify";
|
||||
import { z } from "zod";
|
||||
import { captureFeedback, type FeedbackEventProperties } from "../lib/analytics.js";
|
||||
import {
|
||||
captureFeedback,
|
||||
FEEDBACK_SOURCE_VALUES,
|
||||
FEEDBACK_SURVEY_ID_VALUES,
|
||||
type FeedbackEventProperties,
|
||||
} from "../lib/analytics.js";
|
||||
import { analyticsEnabled } from "../lib/analytics-gate.js";
|
||||
import { requireAuth } from "../plugins/auth.js";
|
||||
|
||||
const SOURCE_VALUES = [
|
||||
"global",
|
||||
"tool_result",
|
||||
"failed_job",
|
||||
"admin_installer",
|
||||
"search_miss",
|
||||
] as const;
|
||||
const SURVEY_ID_VALUES = [
|
||||
"global-feedback-v1",
|
||||
"tool-result-v1",
|
||||
"failed-job-v1",
|
||||
"admin-install-v1",
|
||||
"search-miss-v1",
|
||||
] as const;
|
||||
const SENTIMENT_VALUES = ["great", "okay", "issue", "missing", "bug", "idea", "other"] as const;
|
||||
const FEEDBACK_TYPE_VALUES = [
|
||||
"bug",
|
||||
@@ -84,8 +75,8 @@ const optionalText = (max: number) =>
|
||||
|
||||
const feedbackBodySchema = z
|
||||
.object({
|
||||
source: z.enum(SOURCE_VALUES),
|
||||
surveyId: z.enum(SURVEY_ID_VALUES).optional(),
|
||||
source: z.enum(FEEDBACK_SOURCE_VALUES),
|
||||
surveyId: z.enum(FEEDBACK_SURVEY_ID_VALUES).optional(),
|
||||
promptVariant: z
|
||||
.string()
|
||||
.trim()
|
||||
|
||||
Reference in New Issue
Block a user