mirror of
https://github.com/MBombeck/HealthLog.git
synced 2026-11-11 05:42:19 +00:00
feat(insights): add on-demand full assessment warm
Add POST /api/insights/pregenerate so every AI assessment text — the
comprehensive insight, the seven specialised status cards, and every
data-bearing generic metric assessment — can be warmed for the calling
user on demand, in the active locale, instead of waiting for the nightly
cron or a lazy first-visit generation.
The route narrows userId from the session/Bearer, runs the assistant
surface gate, and enqueues a forced full-warm job onto the existing
insight-pregenerate queue, returning immediately. A short per-user bucket
(insights-warm:<userId>, one per three minutes) returns 429 on a tight
loop so the bypassed nightly 20h budget cannot be turned into a provider
cost amplifier.
The worker branches on the payload: a job carrying { userId, force }
runs forceWarmUser for that user, skipping the candidate scan and the
20h budget; a scheduled tick with no payload keeps its existing batch
behaviour. forceWarmUser reuses the existing comprehensive generator and
warm helpers — no new generation logic — and stays safe by construction:
the comprehensive generator no-ops without a provider, the generic warm
pass filters to metrics the user has rows for so an empty metric never
reaches the provider, and every write is idempotent.
The queue name and a generator-free enqueue helper move to
insight-pregenerate-shared.ts, mirroring the insight-status-generate
split, so the route enqueues without pulling the generator tree.
Regenerate the OpenAPI contract for the new route.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
(cherry picked from commit e10ae9bfeca544c7e5aecd9102459d97ddfad6db)
This commit is contained in:
1 parent
d81ab69dc8
commit
bf5052bb01
7 files changed
+483
-4
No files matched your search
@@ -1927,6 +1927,33 @@ paths:
|
||||
"401": *a1
|
||||
"422": *a2
|
||||
"429": *a3
|
||||
/api/insights/pregenerate:
|
||||
post:
|
||||
tags:
|
||||
- Insights
|
||||
summary: Warm all AI assessments for the calling user
|
||||
description: v1.8.7.1 — enqueue a full warm of every AI assessment for the authenticated user (comprehensive insight +
|
||||
the seven specialised status cards + every data-bearing generic metric assessment) in the active locale, so the
|
||||
read-only status GETs serve cached text instantly. Returns immediately; the generation runs out of band on the
|
||||
worker. Empty metrics and provider-less accounts never trigger an LLM call. Short anti-spam bucket
|
||||
(`insights-warm:<userId>`, one warm per 3 minutes) → 429 on a tight loop. Auth via cookie or Bearer; `userId` is
|
||||
taken from the session, never the body.
|
||||
requestBody:
|
||||
required: false
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: "#/components/schemas/InsightsPregenerateRequest"
|
||||
responses:
|
||||
"200":
|
||||
description: Warm accepted and enqueued. The work runs on the worker; poll the read-only status routes for the text.
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: "#/components/schemas/InsightsPregenerateResponseEnvelope"
|
||||
"401": *a1
|
||||
"422": *a2
|
||||
"429": *a3
|
||||
/api/insights/metric-status:
|
||||
get:
|
||||
tags:
|
||||
@@ -2767,6 +2794,11 @@ components:
|
||||
required:
|
||||
- rating
|
||||
description: Per-message helpful/unhelpful feedback (v1.4.23 H7). Optional `reason` is free-form prose, capped at 200 chars.
|
||||
InsightsPregenerateRequest:
|
||||
type: object
|
||||
properties: {}
|
||||
description: No body fields. The user is taken from the session / Bearer and the locale from the session; the warm
|
||||
covers every assessment for that user.
|
||||
MedicationTreatmentClass:
|
||||
type: string
|
||||
enum:
|
||||
@@ -6267,6 +6299,41 @@ components:
|
||||
additionalProperties: false
|
||||
description: AI-generated insights bundle. Strict-schema validated server-side; Coach-routed when the insight surface
|
||||
needs day-level grounding.
|
||||
InsightsPregenerateResponseEnvelope:
|
||||
type: object
|
||||
properties:
|
||||
data:
|
||||
$ref: "#/components/schemas/InsightsPregenerateResponse"
|
||||
error:
|
||||
type: "null"
|
||||
meta:
|
||||
type: object
|
||||
properties:
|
||||
requestId:
|
||||
type: string
|
||||
additionalProperties: false
|
||||
required:
|
||||
- data
|
||||
- error
|
||||
additionalProperties: false
|
||||
InsightsPregenerateResponse:
|
||||
type: object
|
||||
properties:
|
||||
queued:
|
||||
type: boolean
|
||||
description: True when the full warm was accepted and enqueued.
|
||||
locale:
|
||||
type: string
|
||||
enum:
|
||||
- de
|
||||
- en
|
||||
description: The locale the assessments are being warmed in.
|
||||
required:
|
||||
- queued
|
||||
- locale
|
||||
additionalProperties: false
|
||||
description: Acknowledgement that a full assessment warm was enqueued for the calling user. The generation runs out of
|
||||
band; the text lands in the read-only status routes.
|
||||
MetricStatusResponseEnvelope:
|
||||
type: object
|
||||
properties:
|
||||
|
||||
Reference in new issue
Block a user