User Feedback
Overview
The User Feedback feature is designed to collect and display user feedback and analytics. It includes mechanisms to manage user actions through rate limiting, ensuring that users can provide feedback without overwhelming the system. This feature is crucial for maintaining a responsive and user-friendly experience.
User-facing behavior
- Users can submit feedback through a designated interface.
- Feedback submissions are subject to rate limits to prevent abuse.
- Users receive notifications if they attempt to submit feedback beyond their allowed limit.
- Feedback is aggregated and displayed to users, allowing them to see how their input contributes to the overall user experience.
Architecture and data flow
- The feature leverages a rate limiting system to control how often users can submit feedback.
- When a user submits feedback, their action is checked against the rate limit.
- If the user is within their limit, the feedback is recorded in the database, and the user is notified of their remaining submissions.
- If the user exceeds their limit, they receive a message indicating when they can submit feedback again.
- The system tracks daily usage and resets at midnight UTC.
Key implementation details
- The rate limiting is implemented in the
rate-limit.tsfile, which manages user actions and limits based on a daily quota.
const DEFAULT_DAILY_LIMIT = 5;
const getDailyGenerationLimit = (): number => {
const configured = Number.parseInt(process.env['DAILY_WIKI_GENERATION_LIMIT'] ?? '', 10);
if (!Number.isFinite(configured) || configured <= 0) {
return DEFAULT_DAILY_LIMIT;
}
return configured;
};
This code defines a default daily limit for feedback submissions and allows for configuration through environment variables apps/web/src/lib/auth/rate-limit.ts:6-15.
- The
getDailyGenerationUsagefunction retrieves the current usage statistics for a user.
export const getDailyGenerationUsage = async (
workosUserId: string,
): Promise<DailyGenerationUsage> => {
const { db, generationRateLimits } = await loadDb();
let user;
try {
user = await getStoredUserByWorkOSId(workosUserId);
} catch (error) {
throw new RateLimitError(
'Failed to load user for rate limiting.',
'RATE_LIMIT_USER_LOAD',
500,
{
cause: error,
},
);
}
const dailyLimit = getDailyGenerationLimit();
// Additional logic...
};
This function checks the user's current feedback submission count and compares it to the daily limit, returning the usage statistics apps/web/src/lib/auth/rate-limit.ts:36-64.
- The
incrementDailyGenerationCountfunction is responsible for updating the user's submission count.
export const incrementDailyGenerationCount = async (
workosUserId: string,
): Promise<RateLimitResult> => {
const { db, generationRateLimits } = await loadDb();
let user;
try {
user = await getStoredUserByWorkOSId(workosUserId);
} catch (error) {
throw new RateLimitError(
'Failed to load user for rate limiting.',
'RATE_LIMIT_USER_LOAD',
500,
{
cause: error,
},
);
}
const dailyLimit = getDailyGenerationLimit();
const bucketDate = getCurrentBucketDate();
const now = new Date();
const [counter] = await db
.insert(generationRateLimits)
.values({
userId: user.id,
bucketDate,
count: 1,
createdAt: now,
updatedAt: now,
})
.onConflict(/* conflict handling logic */);
// Additional logic...
};
This function increments the user's submission count and handles potential conflicts in the database apps/web/src/lib/auth/rate-limit.ts:66-100.
Key files
apps/web/src/lib/auth/rate-limit.ts- Manages rate limiting for user actions, including fetching user data and updating submission counts. This file is central to the User Feedback feature's functionality and ensures that feedback submissions are controlled and tracked effectively.