ReadonlyconfigReadonlyserviceStable, human-readable name for the service. Must be set explicitly on each subclass
because this.constructor.name gets mangled by minification in production builds,
which breaks tracing/observability span names.
ProtectedloggerOptionalauditQuestionIds?: AuditQuestionId[]Present only on a batch of a split run. Its presence means the questions were already chosen by the planning delivery, so a batch neither resumes nor re-plans.
Nullable: trigger-sourced runs may have no attributable user.
OptionalforceSlices?: booleanSet by an explicit re-run; see RunChartReviewJobbable.
OptionaltreatmentEpisodeId?: TreatmentEpisodeId | nullEpisode the review is scoped to — limits the run's candidate charts to this episode so other
episodes' charts can't enter the LLM context. .nullish() only so jobs already on the queue
before this field existed still validate during deploy; the enqueue path always populates it.
Idempotency key for queue dedup (see @repo/services trigger-keys.ts).
ProtectedderiveDerive the queue retentionSeconds from the effective dedup TTL. The queue overloads
retentionSeconds — it's BOTH the message lifetime AND the idempotency dedup window
(min(retentionSeconds, 24h)). So:
ttlHours·3600), capped at 24h (the window can't exceed it);delaySeconds + every retry),
else a short TTL would expire the message mid-retry — and the queue hard-rejects
delaySeconds > retentionSeconds.
ttlHours <= 0 means "no dedup" → undefined: the idempotency key is dropped (see
performLater), so there's no dedup window to bound — this just leaves the queue's default
message lifetime in place.Extract an entityId from params for job_executions tracking. Override in subclasses when applicable.
OptionalauditQuestionIds?: AuditQuestionId[]Present only on a batch of a split run. Its presence means the questions were already chosen by the planning delivery, so a batch neither resumes nor re-plans.
Nullable: trigger-sourced runs may have no attributable user.
OptionalforceSlices?: booleanSet by an explicit re-run; see RunChartReviewJobbable.
OptionaltreatmentEpisodeId?: TreatmentEpisodeId | nullEpisode the review is scoped to — limits the run's candidate charts to this episode so other
episodes' charts can't enter the LLM context. .nullish() only so jobs already on the queue
before this field existed still validate during deploy; the enqueue path always populates it.
Idempotency key for queue dedup (see @repo/services trigger-keys.ts).
NOT the parent's triggerKey — keys match globally by string, so it would hit the parent.
OptionalauditQuestionIds?: AuditQuestionId[]Present only on a batch of a split run. Its presence means the questions were already chosen by the planning delivery, so a batch neither resumes nor re-plans.
Nullable: trigger-sourced runs may have no attributable user.
OptionalforceSlices?: booleanSet by an explicit re-run; see RunChartReviewJobbable.
OptionaltreatmentEpisodeId?: TreatmentEpisodeId | nullEpisode the review is scoped to — limits the run's candidate charts to this episode so other
episodes' charts can't enter the LLM context. .nullish() only so jobs already on the queue
before this field existed still validate during deploy; the enqueue path always populates it.
Idempotency key for queue dedup (see @repo/services trigger-keys.ts).
ProtectedllmSame identity its settings resolve against, so routing and the run's levers agree.
OptionalauditQuestionIds?: AuditQuestionId[]Present only on a batch of a split run. Its presence means the questions were already chosen by the planning delivery, so a batch neither resumes nor re-plans.
Nullable: trigger-sourced runs may have no attributable user.
OptionalforceSlices?: booleanSet by an explicit re-run; see RunChartReviewJobbable.
OptionaltreatmentEpisodeId?: TreatmentEpisodeId | nullEpisode the review is scoped to — limits the run's candidate charts to this episode so other
episodes' charts can't enter the LLM context. .nullish() only so jobs already on the queue
before this field existed still validate during deploy; the enqueue path always populates it.
Idempotency key for queue dedup (see @repo/services trigger-keys.ts).
OptionalauditQuestionIds?: AuditQuestionId[]Present only on a batch of a split run. Its presence means the questions were already chosen by the planning delivery, so a batch neither resumes nor re-plans.
Nullable: trigger-sourced runs may have no attributable user.
OptionalforceSlices?: booleanSet by an explicit re-run; see RunChartReviewJobbable.
OptionaltreatmentEpisodeId?: TreatmentEpisodeId | nullEpisode the review is scoped to — limits the run's candidate charts to this episode so other
episodes' charts can't enter the LLM context. .nullish() only so jobs already on the queue
before this field existed still validate during deploy; the enqueue path always populates it.
Idempotency key for queue dedup (see @repo/services trigger-keys.ts).
Enqueue this job for async processing via the configured queue driver (VQS_DRIVER).
Checks for deduplication via job_executions before sending.
OptionalauditQuestionIds?: AuditQuestionId[]Present only on a batch of a split run. Its presence means the questions were already chosen by the planning delivery, so a batch neither resumes nor re-plans.
Nullable: trigger-sourced runs may have no attributable user.
OptionalforceSlices?: booleanSet by an explicit re-run; see RunChartReviewJobbable.
OptionaltreatmentEpisodeId?: TreatmentEpisodeId | nullEpisode the review is scoped to — limits the run's candidate charts to this episode so other
episodes' charts can't enter the LLM context. .nullish() only so jobs already on the queue
before this field existed still validate during deploy; the enqueue path always populates it.
Idempotency key for queue dedup (see @repo/services trigger-keys.ts).
Optionaloptions: PerformLaterOptionsOptionalauditQuestionIds?: AuditQuestionId[]Present only on a batch of a split run. Its presence means the questions were already chosen by the planning delivery, so a batch neither resumes nor re-plans.
Nullable: trigger-sourced runs may have no attributable user.
OptionalforceSlices?: booleanSet by an explicit re-run; see RunChartReviewJobbable.
OptionaltreatmentEpisodeId?: TreatmentEpisodeId | nullEpisode the review is scoped to — limits the run's candidate charts to this episode so other
episodes' charts can't enter the LLM context. .nullish() only so jobs already on the queue
before this field existed still validate during deploy; the enqueue path always populates it.
Idempotency key for queue dedup (see @repo/services trigger-keys.ts).
Run the job with status tracking. Used by the queue handler. Errors propagate (not caught by safe()) so the RetryHandler can decide.
parentSpanContext (the enqueuer's span, recovered from the queue envelope) is attached
as a span LINK and the run span is started as a new trace root, so each job runs in its
own trace rather than collapsing a fan-out into one unbounded trace.
ProtectedspanOptional hook for subclasses to attach extra non-PII span attributes derived from params.
The returned attributes appear on the service.${serviceName} span (and, for jobs,
on job.enqueue.* and job.run.* spans too).
Safe ID-like keys on params (e.g. patientId, templateIds, limit, cursor) are
already auto-extracted via toSpanAttributes("service.input", params) — you don't need
to enumerate them here. Use this hook for derived/computed attributes (counts, flags,
computed names) or for fields you've explicitly verified safe but that aren't in the
global allowlist. Hook output overrides auto-extracted attributes on key collision.
Safe by default: returns {} when not overridden. Only declare keys you've confirmed
are non-PII. Never include emails, names, dob, free-text, etc.
OptionalauditQuestionIds?: AuditQuestionId[]Present only on a batch of a split run. Its presence means the questions were already chosen by the planning delivery, so a batch neither resumes nor re-plans.
Nullable: trigger-sourced runs may have no attributable user.
OptionalforceSlices?: booleanSet by an explicit re-run; see RunChartReviewJobbable.
OptionaltreatmentEpisodeId?: TreatmentEpisodeId | nullEpisode the review is scoped to — limits the run's candidate charts to this episode so other
episodes' charts can't enter the LLM context. .nullish() only so jobs already on the queue
before this field existed still validate during deploy; the enqueue path always populates it.
Idempotency key for queue dedup (see @repo/services trigger-keys.ts).
ProtectedspanOptional hook for subclasses to attach extra non-PII span attributes derived from the
successful service result. Only called when run resolves successfully; on error, the
span is marked via markSpanError instead.
Safe by default: returns {} when not overridden. Only declare keys you've confirmed
are non-PII (e.g. counts, status flags, computed summaries). Never include emails,
names, dob, free-text, etc.
Without its questions a batch would re-run the whole template under one shared key. The schema
is .nonempty(), so only the absent case is left to reject here.
One batch of a split triggered run. Its own topic so batch throughput is tuned separately from the planning deliveries — sharing
run-triggered-chart-reviewwould put planners behind batches, and a throttled queue would stop new triggered reviews being planned at all.