feat(ops): /ops/v1/summary med ai/aktivering/engagemang/betalning/jobb/sakerhet + canary
- Nya toppnivåblock i /ops/v1/summary: ai_scan, aktivering, engagemang, betalning, jobb, sakerhet. Alla värden läses från DB/cache; null där data saknas, inga påhittade värden. - AI-kostnad i USD mikrocent (native); intäkter fortsatt SEK-öre. - product_analytics_events är källa för volym, latens, lyckandegrad, felfrekvens, aktivering, retention och engagemang. - Nya händelser: scan_started (API) och scan_failed/scan_completed med latencyMs + felkod (worker). latencyMs flödar nu in i scan_completed. - Safety canary-jobb varje timme: re-härleder allergener för alla recept, räknar överifierade publika recept och food-safety-lint; skriver EN rad till ops_safety_canary. Endpointen läser endast sista raden. - Cache-refresh-jobb var 60 s skriver hela summariet till Redis; endpointen serverar cachen med 503 vid cache-miss. - Bearer-token-skydd med OPS_TOKEN; HTTPS-tvång i produktion; ingen PII. - Tester för endpoint, auth, cache-miss och safety canary.
This commit is contained in:
@@ -18,5 +18,6 @@ export * from "./memory.js";
|
||||
export * from "./seasons.js";
|
||||
export * from "./subscriptions.js";
|
||||
export * from "./analytics.js";
|
||||
export * from "./ops.js";
|
||||
export * from "./platform.js";
|
||||
export * from "./releaseGates.js";
|
||||
|
||||
@@ -0,0 +1,17 @@
|
||||
import { integer, pgTable, timestamp, uuid } from "drizzle-orm/pg-core";
|
||||
|
||||
/**
|
||||
* Safety canary: hourly deterministic checks written by a worker job and
|
||||
* read by the ops endpoint. The endpoint never runs heavy computations.
|
||||
*/
|
||||
export const opsSafetyCanary = pgTable("ops_safety_canary", {
|
||||
id: uuid("id").primaryKey().defaultRandom(),
|
||||
occurredAt: timestamp("occurred_at", { withTimezone: true }).notNull().defaultNow(),
|
||||
/** Recipes where stored allergens differ from freshly derived allergens. */
|
||||
allergenInvariantBrott: integer("allergen_invariant_brott").notNull().default(0),
|
||||
/** Publicly visible recipes that are not verificationStatus=verified. */
|
||||
overifieradeVisade: integer("overifierade_visade").notNull().default(0),
|
||||
/** Recipes rejected by the food-safety lint in the last 7 days. */
|
||||
foodSafetyLintAvvisade7d: integer("food_safety_lint_avvisade_7d"),
|
||||
computedAt: timestamp("computed_at", { withTimezone: true }).notNull().defaultNow(),
|
||||
});
|
||||
Reference in New Issue
Block a user