feat: Responsive admin UI, SEO pages, and click analytics
## Responsive Admin UI - Layout.tsx: Mobile sidebar drawer with hamburger menu - Dashboard.tsx: 2-col grid on mobile, responsive stats cards - OrchestratorDashboard.tsx: Responsive table with hidden columns - PagesTab.tsx: Responsive filters and table ## SEO Pages - New /admin/seo section with state landing pages - SEO page generation and management - State page content with dispensary/product counts ## Click Analytics - Product click tracking infrastructure - Click analytics dashboard ## Other Changes - Consumer features scaffolding (alerts, deals, favorites) - Health panel component - Workers dashboard improvements - Legacy DutchieAZ pages removed 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
@@ -447,5 +447,55 @@ export function createMultiStateRoutes(pool: Pool): Router {
|
||||
}
|
||||
});
|
||||
|
||||
// =========================================================================
|
||||
// Health Check Endpoint
|
||||
// =========================================================================
|
||||
|
||||
/**
|
||||
* GET /api/health/analytics
|
||||
* Health check for analytics subsystem
|
||||
*/
|
||||
router.get('/health/analytics', async (req: Request, res: Response) => {
|
||||
try {
|
||||
const startTime = Date.now();
|
||||
|
||||
// Check materialized view is accessible
|
||||
const result = await pool.query(`
|
||||
SELECT COUNT(*) as state_count,
|
||||
MAX(refreshed_at) as last_refresh
|
||||
FROM mv_state_metrics
|
||||
`);
|
||||
|
||||
const dbLatency = Date.now() - startTime;
|
||||
const stateCount = parseInt(result.rows[0]?.state_count || '0', 10);
|
||||
const lastRefresh = result.rows[0]?.last_refresh;
|
||||
|
||||
// Check if data is stale (more than 24 hours old)
|
||||
const isStale = lastRefresh
|
||||
? Date.now() - new Date(lastRefresh).getTime() > 24 * 60 * 60 * 1000
|
||||
: true;
|
||||
|
||||
res.json({
|
||||
success: true,
|
||||
status: isStale ? 'degraded' : 'healthy',
|
||||
data: {
|
||||
statesInCache: stateCount,
|
||||
lastRefresh: lastRefresh || null,
|
||||
isStale,
|
||||
dbLatencyMs: dbLatency,
|
||||
},
|
||||
timestamp: new Date().toISOString(),
|
||||
});
|
||||
} catch (error: any) {
|
||||
console.error('[MultiState] Health check failed:', error);
|
||||
res.status(503).json({
|
||||
success: false,
|
||||
status: 'unhealthy',
|
||||
error: error.message,
|
||||
timestamp: new Date().toISOString(),
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
return router;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user