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.
ProtectedloggerOptionalchartReviewJobs?: {Optionalmanual?: { createdBy: UserId; templateIds: AuditTemplateId[] }Present when the run is UI-initiated (Sync & Run). Routes to the manual enqueue pipeline.
Extract an entityId from params for job_executions tracking. Override in subclasses when applicable.
OptionalchartReviewJobs?: {Optionalmanual?: { createdBy: UserId; templateIds: AuditTemplateId[] }Present when the run is UI-initiated (Sync & Run). Routes to the manual enqueue pipeline.
NEW key format (deliberately ≠ v1's patient_{id}sync…). The :scheduled token mirrors
v1: a pending scheduled review must force a fresh doc sync even when a non-scheduled
sync ran inside the TTL window. Manual runs return null so they aren't deduped against
an in-flight triggered sync for the same episode (the manual templateIds would be dropped).
OptionalchartReviewJobs?: {Optionalmanual?: { createdBy: UserId; templateIds: AuditTemplateId[] }Present when the run is UI-initiated (Sync & Run). Routes to the manual enqueue pipeline.
OptionalchartReviewJobs?: {Optionalmanual?: { createdBy: UserId; templateIds: AuditTemplateId[] }Present when the run is UI-initiated (Sync & Run). Routes to the manual enqueue pipeline.
Enqueue this job for async processing via Vercel Queues. Checks for deduplication via job_executions before sending.
OptionalchartReviewJobs?: {Optionalmanual?: { createdBy: UserId; templateIds: AuditTemplateId[] }Present when the run is UI-initiated (Sync & Run). Routes to the manual enqueue pipeline.
Optionaloptions: PerformLaterOptionsOptionalchartReviewJobs?: {Optionalmanual?: { createdBy: UserId; templateIds: AuditTemplateId[] }Present when the run is UI-initiated (Sync & Run). Routes to the manual enqueue pipeline.
Run the job with status tracking. Used by the queue handler. Errors propagate (not caught by safe()) so the RetryHandler can decide.
OptionalchartReviewJobs?: {Optionalmanual?: { createdBy: UserId; templateIds: AuditTemplateId[] }Present when the run is UI-initiated (Sync & Run). Routes to the manual enqueue pipeline.
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.
OptionalchartReviewJobs?: {Optionalmanual?: { createdBy: UserId; templateIds: AuditTemplateId[] }Present when the run is UI-initiated (Sync & Run). Routes to the manual enqueue pipeline.
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.
Per-episode EMR sync (episode-first port of v1 sync-patient): episode-scoped sync, treatment_episodes dual-write (both models maintained during the transition window), documents when reviews are pending, then the chart reviews — docs always precede reviews. Routes to the manual enqueue pipeline when
manualis set, otherwise to the triggered pipeline. Returns theauditRunIdsfrom whichever enqueue ran.