Phase 0 - Foundation: - Restructure into npm workspace monorepo (packages/core, api, scraper) - PostgreSQL 17 + TimescaleDB schema (15 tables incl. hypertables) - Docker Compose for local dev (PostgreSQL on 5433 + Qdrant) - Express 5 API on port 3200 with 6 routes - Seed script to migrate 159 transceivers + 42 standards from npm package - Erik server setup script + PM2 ecosystem config Phase 1 - Scraper Engine: - Crawlee + Playwright framework with pg-boss scheduler - FS.com scraper (PlaywrightCrawler, anti-bot workaround) - Optcore.net scraper (WP REST API enumeration + PlaywrightCrawler) - Uses /wp-json/wp/v2/product to get 2000+ product URLs - Playwright renders individual product pages for price extraction - Cisco TMG Matrix scraper (compatibility data) - News RSS aggregator (optics.org, SPIE, Network World, Nature Photonics) - Keyword relevance scoring for transceiver/fiber topics - xml2js with malformed XML sanitization - SHA-256 content hashing for change detection (skip unchanged records) - pg-boss v10 with explicit queue creation before scheduling
33 lines
798 B
TypeScript
33 lines
798 B
TypeScript
import { Router, Request, Response } from "express";
|
|
import { getDbStats } from "../db/queries";
|
|
import { pool } from "../db/client";
|
|
|
|
export const healthRouter = Router();
|
|
|
|
// GET /api/health — Health check with DB stats
|
|
healthRouter.get("/", async (_req: Request, res: Response) => {
|
|
try {
|
|
const start = Date.now();
|
|
const stats = await getDbStats();
|
|
const latencyMs = Date.now() - start;
|
|
|
|
res.json({
|
|
success: true,
|
|
status: "healthy",
|
|
version: "0.1.0",
|
|
uptime: process.uptime(),
|
|
database: {
|
|
connected: true,
|
|
latency_ms: latencyMs,
|
|
stats,
|
|
},
|
|
});
|
|
} catch (err) {
|
|
res.status(503).json({
|
|
success: false,
|
|
status: "unhealthy",
|
|
database: { connected: false, error: String(err) },
|
|
});
|
|
}
|
|
});
|