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>
27 lines
794 B
TypeScript
27 lines
794 B
TypeScript
import type { JobDefinition } from "@trails-cool/jobs";
|
|
import {
|
|
demoRetentionDays,
|
|
isDemoBotEnabled,
|
|
pruneSynthetic,
|
|
refreshDemoBotGauges,
|
|
} from "../lib/demo-bot.server.ts";
|
|
import { logger } from "../lib/logger.server.ts";
|
|
|
|
/**
|
|
* Daily prune. Deletes synthetic rows older than
|
|
* `DEMO_BOT_RETENTION_DAYS` (default 14). Never touches real users.
|
|
*/
|
|
export const demoBotPruneJob: JobDefinition = {
|
|
name: "demo-bot:prune",
|
|
cron: "15 3 * * *",
|
|
retryLimit: 1,
|
|
expireInSeconds: 60,
|
|
async handler() {
|
|
if (!isDemoBotEnabled()) return { skipped: "disabled" };
|
|
const days = demoRetentionDays();
|
|
const counts = await pruneSynthetic(days);
|
|
logger.info({ days, ...counts }, "demo-bot prune");
|
|
await refreshDemoBotGauges();
|
|
return { days, ...counts };
|
|
},
|
|
};
|