6ab52a2499
Backend & Auth: - Add @clerk/nextjs for production authentication - Create src/proxy.ts with clerkMiddleware() for route protection - Implement multi-tenant auth with role-based access control - Add Clerk components (Show, UserButton, SignInButton, SignUpButton) Billing & Payments: - Full Stripe integration (subscriptions, add-ons, customer portal) - Plan tiers: Starter 9/mo, Farm 49/mo, Enterprise 99/mo - Webhook handling for subscription events - createSubscription(), createAddonSubscription(), createCustomerPortalSession() API & Security: - Rate limiting with @upstash/ratelimit (100 req/min API, 20 req/min checkout) - Zod validation schemas for all endpoints (orders, products, campaigns, etc.) - Security headers (CSP, HSTS, X-Frame-Options) - API routes: /api/v1/ with validated, rate-limited endpoints Monitoring: - Sentry error tracking with performance monitoring - PostHog analytics for feature usage, funnels, cohorts - User activity logging and breadcrumb tracking Admin Features: - Analytics dashboard with revenue charts, customer growth, conversion funnel - Onboarding flow with 6-step interactive tour - Referral system with share tracking and reward redemption - Changelog feed with in-app notifications PWA & SEO: - Web app manifest with icons and shortcuts - Service worker for offline support and caching - Full SEO metadata, OpenGraph, Twitter cards - Structured data (JSON-LD) for organization and products Database: - Add referral_codes, changelogs, onboarding_progress tables - Add user_activity_logs, api_keys, notification_preferences - Comprehensive RLS policies for all new tables - Seed data for demo brands and products
94 lines
2.5 KiB
TypeScript
94 lines
2.5 KiB
TypeScript
// Global Error Handler for uncaught exceptions
|
|
|
|
import { captureError, addBreadcrumb } from "./sentry";
|
|
|
|
// Handle uncaught errors
|
|
if (typeof window !== "undefined") {
|
|
window.onerror = (message, source, lineno, colno, error) => {
|
|
captureError(error || new Error(String(message)), {
|
|
source,
|
|
lineno,
|
|
colno,
|
|
type: "uncaught_error",
|
|
});
|
|
return false;
|
|
};
|
|
|
|
// Handle unhandled promise rejections
|
|
window.onunhandledrejection = (event) => {
|
|
captureError(
|
|
event.reason instanceof Error
|
|
? event.reason
|
|
: new Error(String(event.reason)),
|
|
{
|
|
type: "unhandled_rejection",
|
|
promise: event.promise ? String(event.promise) : undefined,
|
|
}
|
|
);
|
|
};
|
|
}
|
|
|
|
// Add breadcrumb for page navigation
|
|
export function trackPageNavigation(path: string) {
|
|
addBreadcrumb(`Navigated to ${path}`, { path });
|
|
}
|
|
|
|
// Add breadcrumb for user actions
|
|
export function trackUserAction(action: string, details?: Record<string, unknown>) {
|
|
addBreadcrumb(`User action: ${action}`, { action, ...details });
|
|
}
|
|
|
|
// Performance monitoring
|
|
export function measurePerformance(name: string, callback: () => void | Promise<void>) {
|
|
const start = performance.now();
|
|
|
|
const measure = async () => {
|
|
await callback();
|
|
const duration = performance.now() - start;
|
|
|
|
addBreadcrumb(`Performance: ${name}`, {
|
|
name,
|
|
duration: `${duration.toFixed(2)}ms`,
|
|
});
|
|
};
|
|
|
|
return measure();
|
|
}
|
|
|
|
// API call tracking
|
|
export async function trackApiCall<T>(
|
|
endpoint: string,
|
|
method: string,
|
|
fn: () => Promise<T>
|
|
): Promise<T> {
|
|
addBreadcrumb(`API call: ${method} ${endpoint}`, { endpoint, method });
|
|
|
|
try {
|
|
const result = await fn();
|
|
addBreadcrumb(`API success: ${method} ${endpoint}`, { endpoint, method, success: true });
|
|
return result;
|
|
} catch (error) {
|
|
captureError(error as Error, { endpoint, method });
|
|
addBreadcrumb(`API error: ${method} ${endpoint}`, { endpoint, method, success: false });
|
|
throw error;
|
|
}
|
|
}
|
|
|
|
// Debug logging for development
|
|
export const debugLog = {
|
|
info: (message: string, data?: unknown) => {
|
|
if (process.env.NODE_ENV === "development") {
|
|
console.info(`[DEBUG] ${message}`, data);
|
|
}
|
|
},
|
|
warn: (message: string, data?: unknown) => {
|
|
if (process.env.NODE_ENV === "development") {
|
|
console.warn(`[DEBUG] ${message}`, data);
|
|
}
|
|
},
|
|
error: (message: string, data?: unknown) => {
|
|
if (process.env.NODE_ENV === "development") {
|
|
console.error(`[DEBUG] ${message}`, data);
|
|
}
|
|
},
|
|
}; |