Adds a background demo user (`bruno`) plus two pg-boss jobs that generate public trekking routes and activities in inner Berlin and prune them after 14 days. Disabled by default everywhere; flip `DEMO_BOT_ENABLED` only in prod. - Schema: `synthetic` boolean on routes + activities - `ensureDemoUser()` idempotent insert + badge on /users/bruno - Generation gate: 07-21 Berlin local, p=0.12, 40-route cap in 14d - Initial 4-walk backfill on first enable; retention via daily prune - Prometheus gauges `demo_bot_synthetic_routes_total` / `_activities_total` - Unit + DB-gated integration + E2E tests Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
28 lines
997 B
TypeScript
28 lines
997 B
TypeScript
import client from "prom-client";
|
|
|
|
// Collect default Node.js metrics (event loop, heap, GC)
|
|
client.collectDefaultMetrics();
|
|
|
|
export const httpRequestDuration = new client.Histogram({
|
|
name: "http_request_duration_seconds",
|
|
help: "Duration of HTTP requests in seconds",
|
|
labelNames: ["method", "route", "status"] as const,
|
|
buckets: [0.01, 0.05, 0.1, 0.25, 0.5, 1, 2.5, 5],
|
|
});
|
|
|
|
/**
|
|
* Count of synthetic demo-bot routes currently in the database. Scraped
|
|
* by the background worker after each generation run so the Grafana
|
|
* board stays live without a /metrics handler on the worker process.
|
|
*/
|
|
export const demoBotSyntheticRoutesTotal = new client.Gauge({
|
|
name: "demo_bot_synthetic_routes_total",
|
|
help: "Total synthetic demo-bot routes currently stored",
|
|
});
|
|
|
|
export const demoBotSyntheticActivitiesTotal = new client.Gauge({
|
|
name: "demo_bot_synthetic_activities_total",
|
|
help: "Total synthetic demo-bot activities currently stored",
|
|
});
|
|
|
|
export const registry = client.register;
|