Structural completeness check for chiropractic SOAP notes. Takes a note string, returns a pass/fail flag, a 0–100 quality score, and a list of specific findings so callers know exactly what's missing.
Used inside ChiroScribe to gate AI-generated SOAP notes before they reach a provider for review. Open-sourced because the rules are general enough that any chiropractic EHR, scribe, or audit tool can benefit.
npm install @chiroscribe/soap-note-validatorimport { validateSoapNote } from '@chiroscribe/soap-note-validator'
const note = `
Subjective:
Patient reports continued improvement in lumbar mobility. Pain rated 3/10.
Objective:
Lumbar flexion 62 deg (+18 from initial). SLR negative bilaterally.
Assessment:
M54.50 Low back pain — improving.
Plan:
Continue 2x/week for 4 weeks. Progress home exercise program.
`
const result = validateSoapNote(note)
// {
// ok: true,
// score: 100,
// findings: [
// { key: 'icd10_detected', severity: 'info', message: 'Detected ICD-10 codes: M54.50.' }
// ],
// sections: {
// subjective: { present: true, length: 105, meetsMinimumLength: true },
// objective: { present: true, length: 87, meetsMinimumLength: true },
// assessment: { present: true, length: 47, meetsMinimumLength: true },
// plan: { present: true, length: 75, meetsMinimumLength: true }
// },
// detectedIcd10Codes: ['M54.50'],
// detectedFrequencyCues: ['2x/week']
// }| Check | Severity | Default behavior |
|---|---|---|
| All four SOAP sections present | error | Required |
| Each section meets minimum body length | warning | Configurable per-section |
| Assessment contains ≥1 ICD-10 code | error | Required; disable via requireIcd10: false |
| Plan mentions a treatment-frequency cue (e.g. "2x/week", "weekly", "for 4 weeks") | warning | Required; disable via requireFrequencyCue: false |
The validator tolerates common SOAP header variants:
Subjective:/Objective:/Assessment:/Plan:- Short form:
S:/O:/A:/P: - Markdown headings:
## Subjective,### Objective - Emphasized:
**Subjective:**,*Objective:*
Matches the standard ICD-10-CM pattern: [Letter][2 chars](.[1–4 chars])?. Covers:
- Primary diagnoses:
M54.50,M99.03 - Encounter-suffixed trauma codes:
S33.5XXA,S13.4XXD,S16.1XXS - Headache:
G44.209,R51.9
For a curated dataset of chiropractic-relevant ICD-10 codes with Medicare and AT-modifier flags, see the companion repo: @chiroscribe/icd10-chiropractic.
Recognizes common treatment-frequency phrasing:
2x/week,3x/month,1x/daytwice a week,three times per weekweekly,biweekly,monthly,dailyevery 2 weeks,every 3 daysBIW,TIW,BID,TID,QID(medical abbreviations)for 4 weeks,for 3 months(duration cues)
validateSoapNote(note, {
minSubjectiveLength: 40, // default
minObjectiveLength: 40, // default
minAssessmentLength: 20, // default
minPlanLength: 30, // default
requireIcd10: true, // default
requireFrequencyCue: true, // default
})Starts at 100 and deducts:
-20per error finding-8per warning finding0for info findings
A note that fails the ICD-10 requirement (error) and has a short Subjective (warning) scores 100 − 20 − 8 = 72 and ok: false.
This package checks that a SOAP note looks like a real SOAP note — sections present, codes wired in, plan committed to a cadence. It does not check clinical accuracy, diagnostic appropriateness, or medical necessity. Those require a credentialed clinician (or, increasingly, a credentialed clinician + an AI like ChiroScribe's auto-proofread layer).
Structural validation is the cheap, deterministic prerequisite. Get it right and you save your clinical reviewer from rejecting 30% of notes for missing sections — that effort can go to the 5% that actually need clinical judgment.
@chiroscribe/icd10-chiropractic— Curated chiropractic ICD-10 dataset with Medicare flags.- ChiroScribe — Full AI clinical-documentation platform.
Bug reports and PRs welcome. If you have a SOAP note that the validator handles incorrectly, open an issue with the (de-identified) text and we'll add it to the test suite.
MIT — see LICENSE.
Maintained by ChiroScribe LLC.