Include last 4-chars of Dyad Pro user id for bug reports (#1933)
This allows us to identify which Dyad Pro user filed an issue on GitHub by using a partial internal identifier <!-- CURSOR_SUMMARY --> --- > [!NOTE] > Adds a redacted Dyad Pro user ID (last 4 chars) to bug report/session templates, sourced from the Pro user info endpoint and exposed via user budget info. > > - **Frontend (HelpDialog)**: > - Display `Pro User ID` in prefilled bug report and session report bodies using `userBudget.redactedUserId`. > - Consume `useUserBudgetInfo` to access `userBudget`. > - **IPC/Backend**: > - `get-user-budget`: derive `redactedUserId` from `user_info.user_id` (mask all but last 4 chars); include in test mock and response. > - **Types**: > - Extend `UserBudgetInfoSchema` with `redactedUserId: string`. > > <sup>Written by [Cursor Bugbot](https://cursor.com/dashboard?tab=bugbot) for commit 1883a1ef94fec25b370df3d46054fb56d659dee8. This will update automatically on new commits. Configure [here](https://cursor.com/dashboard?tab=bugbot).</sup> <!-- /CURSOR_SUMMARY --> <!-- This is an auto-generated description by cubic. --> --- ## Summary by cubic Adds a redacted Dyad Pro user ID (last 4 chars) to bug report templates to help correlate GitHub issues with Pro accounts while protecting privacy. - **New Features** - Derives redactedUserId from user_info.user_id in the Pro IPC handler and adds it to UserBudgetInfo. - Shows “Pro User ID” in HelpDialog’s debug info and session details. - Extends UserBudgetInfo schema with a redactedUserId field. <sup>Written for commit 1883a1ef94fec25b370df3d46054fb56d659dee8. Summary will update automatically on new commits.</sup> <!-- End of auto-generated description by cubic. -->
This commit is contained in:
@@ -26,6 +26,7 @@ import { showError } from "@/lib/toast";
|
|||||||
import { HelpBotDialog } from "./HelpBotDialog";
|
import { HelpBotDialog } from "./HelpBotDialog";
|
||||||
import { useSettings } from "@/hooks/useSettings";
|
import { useSettings } from "@/hooks/useSettings";
|
||||||
import { BugScreenshotDialog } from "./BugScreenshotDialog";
|
import { BugScreenshotDialog } from "./BugScreenshotDialog";
|
||||||
|
import { useUserBudgetInfo } from "@/hooks/useUserBudgetInfo";
|
||||||
|
|
||||||
interface HelpDialogProps {
|
interface HelpDialogProps {
|
||||||
isOpen: boolean;
|
isOpen: boolean;
|
||||||
@@ -43,7 +44,7 @@ export function HelpDialog({ isOpen, onClose }: HelpDialogProps) {
|
|||||||
const [isBugScreenshotOpen, setIsBugScreenshotOpen] = useState(false);
|
const [isBugScreenshotOpen, setIsBugScreenshotOpen] = useState(false);
|
||||||
const selectedChatId = useAtomValue(selectedChatIdAtom);
|
const selectedChatId = useAtomValue(selectedChatIdAtom);
|
||||||
const { settings } = useSettings();
|
const { settings } = useSettings();
|
||||||
|
const { userBudget } = useUserBudgetInfo();
|
||||||
const isDyadProUser = settings?.providerSettings?.["auto"]?.apiKey?.value;
|
const isDyadProUser = settings?.providerSettings?.["auto"]?.apiKey?.value;
|
||||||
|
|
||||||
// Function to reset all dialog state
|
// Function to reset all dialog state
|
||||||
@@ -103,6 +104,7 @@ Issues that do not meet these requirements will be closed and may need to be res
|
|||||||
- Node Version: ${debugInfo.nodeVersion || "n/a"}
|
- Node Version: ${debugInfo.nodeVersion || "n/a"}
|
||||||
- PNPM Version: ${debugInfo.pnpmVersion || "n/a"}
|
- PNPM Version: ${debugInfo.pnpmVersion || "n/a"}
|
||||||
- Node Path: ${debugInfo.nodePath || "n/a"}
|
- Node Path: ${debugInfo.nodePath || "n/a"}
|
||||||
|
- Pro User ID: ${userBudget?.redactedUserId || "n/a"}
|
||||||
- Telemetry ID: ${debugInfo.telemetryId || "n/a"}
|
- Telemetry ID: ${debugInfo.telemetryId || "n/a"}
|
||||||
- Model: ${debugInfo.selectedLanguageModel || "n/a"}
|
- Model: ${debugInfo.selectedLanguageModel || "n/a"}
|
||||||
|
|
||||||
@@ -226,6 +228,7 @@ Issues that do not meet these requirements will be closed and may need to be res
|
|||||||
-->
|
-->
|
||||||
|
|
||||||
Session ID: ${sessionId}
|
Session ID: ${sessionId}
|
||||||
|
Pro User ID: ${userBudget?.redactedUserId || "n/a"}
|
||||||
|
|
||||||
## Issue Description (required)
|
## Issue Description (required)
|
||||||
<!-- Please describe the issue you're experiencing -->
|
<!-- Please describe the issue you're experiencing -->
|
||||||
|
|||||||
@@ -22,6 +22,7 @@ export function registerProHandlers() {
|
|||||||
usedCredits: 100,
|
usedCredits: 100,
|
||||||
totalCredits: 1000,
|
totalCredits: 1000,
|
||||||
budgetResetDate: resetDate,
|
budgetResetDate: resetDate,
|
||||||
|
redactedUserId: "<redacted-user-id-testing>",
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
logger.info("Attempting to fetch user budget information.");
|
logger.info("Attempting to fetch user budget information.");
|
||||||
@@ -58,11 +59,18 @@ export function registerProHandlers() {
|
|||||||
|
|
||||||
const data = await response.json();
|
const data = await response.json();
|
||||||
const userInfoData = data["user_info"];
|
const userInfoData = data["user_info"];
|
||||||
|
const userId = userInfoData["user_id"];
|
||||||
|
// Turn user_abc1234 => "****1234"
|
||||||
|
// Preserve the last 4 characters so we can correlate bug reports
|
||||||
|
// with the user.
|
||||||
|
const redactedUserId =
|
||||||
|
userId.length > 8 ? "****" + userId.slice(-4) : "<redacted>";
|
||||||
logger.info("Successfully fetched user budget information.");
|
logger.info("Successfully fetched user budget information.");
|
||||||
return UserBudgetInfoSchema.parse({
|
return UserBudgetInfoSchema.parse({
|
||||||
usedCredits: userInfoData["spend"] * CONVERSION_RATIO,
|
usedCredits: userInfoData["spend"] * CONVERSION_RATIO,
|
||||||
totalCredits: userInfoData["max_budget"] * CONVERSION_RATIO,
|
totalCredits: userInfoData["max_budget"] * CONVERSION_RATIO,
|
||||||
budgetResetDate: new Date(userInfoData["budget_reset_at"]),
|
budgetResetDate: new Date(userInfoData["budget_reset_at"]),
|
||||||
|
redactedUserId: redactedUserId,
|
||||||
});
|
});
|
||||||
} catch (error: any) {
|
} catch (error: any) {
|
||||||
logger.error(`Error fetching user budget: ${error.message}`, error);
|
logger.error(`Error fetching user budget: ${error.message}`, error);
|
||||||
|
|||||||
@@ -278,6 +278,7 @@ export const UserBudgetInfoSchema = z.object({
|
|||||||
usedCredits: z.number(),
|
usedCredits: z.number(),
|
||||||
totalCredits: z.number(),
|
totalCredits: z.number(),
|
||||||
budgetResetDate: z.date(),
|
budgetResetDate: z.date(),
|
||||||
|
redactedUserId: z.string(),
|
||||||
});
|
});
|
||||||
export type UserBudgetInfo = z.infer<typeof UserBudgetInfoSchema>;
|
export type UserBudgetInfo = z.infer<typeof UserBudgetInfoSchema>;
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user