AI skill: SKILL.md, AI contract, scrubbed references, eval fixture (d)
- rpa-dashboard-ai/SKILL.md: trigger description and the shared question flow; points at the no-AI frontend.md, themes and palette instead of copying them. - templates/contract.md: runs, review rows, endpoints and the server approve gate. - Superbill extracts: patient names and the client name removed, every file carries an EXAMPLE ONLY banner. tests/test_reference_scan.py checks both skills for patient data, internal IPs, credentials and keys. - tests/fixtures/d-ai-extraction and its eval entry, which runs page_check_ai on the built folder. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
1 parent
91495935b9
commit
8951ac05a5
30 files changed
+372
-26
No files matched your search
@@ -1,3 +1,4 @@
|
||||
/* EXAMPLE ONLY: an extract from the Superbill Review prototype, kept as reference for porting. ECW/eClinicalWorks, Tebra, 'Example Client', SPB_* tables and patient/ticket wording are that project's examples. Don't copy them into a new project. */
|
||||
import { ThemeSwitcher } from '../theme'
|
||||
import { ROLE_LABEL } from '../auth'
|
||||
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
/* EXAMPLE ONLY: an extract from the Superbill Review prototype, kept as reference for porting. ECW/eClinicalWorks, Tebra, 'Example Client', SPB_* tables and patient/ticket wording are that project's examples. Don't copy them into a new project. */
|
||||
/**
|
||||
* A proportional ring.
|
||||
*
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
/* EXAMPLE ONLY: an extract from the Superbill Review prototype, kept as reference for porting. ECW/eClinicalWorks, Tebra, 'Example Client', SPB_* tables and patient/ticket wording are that project's examples. Don't copy them into a new project. */
|
||||
import { useCallback, useEffect, useRef, useState } from 'react'
|
||||
import { useQuery } from '@tanstack/react-query'
|
||||
import { api } from '../api'
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
/* EXAMPLE ONLY: an extract from the Superbill Review prototype, kept as reference for porting. ECW/eClinicalWorks, Tebra, 'Example Client', SPB_* tables and patient/ticket wording are that project's examples. Don't copy them into a new project. */
|
||||
import { useEffect, useMemo, useRef, useState } from 'react'
|
||||
import { useMutation, useQuery, useQueryClient } from '@tanstack/react-query'
|
||||
import { api } from '../api'
|
||||
@@ -12,7 +13,7 @@ const isOfficeLocation = (t: string | null) =>
|
||||
|
||||
// One review card per record on a page. An ECW roster can list the same
|
||||
// person twice (two Sleep Study encounters for one patient) — line_index
|
||||
// splits those into separate cards. A Gulf Coast ticket spreads its charges
|
||||
// splits those into separate cards. A Example Client ticket spreads its charges
|
||||
// over several line_index values and must stay ONE card, so it is excluded.
|
||||
// The name stays in the key so runs stored before line_index existed (every
|
||||
// row LineIndex 0) still group exactly as before.
|
||||
@@ -100,7 +101,7 @@ type Patient = {
|
||||
type SaveArgs = { row: ReviewRow; draft: string; verified: boolean }
|
||||
|
||||
// ── Office Location ────────────────────────────────────────────────────────
|
||||
// A Gulf Coast ticket whose yellow note the Office Location rules read. The
|
||||
// A Example Client ticket whose yellow note the Office Location rules read. The
|
||||
// backend stores the parsed note on the ticket's first line under this field
|
||||
// (src/superbill/extraction/office_location.py, ParsedNote); a ticket without
|
||||
// it is a run from before the rules existed and keeps the flat layout.
|
||||
@@ -191,11 +192,11 @@ export function ReviewPane({
|
||||
}) {
|
||||
const [index, setIndex] = useState(0)
|
||||
// Drafts live here, not in FieldRow — a correction is no longer committed on
|
||||
// blur (that is exactly how four ARMSTRONG fields got saved mid-keystroke:
|
||||
// "ARMSTRONG, CHARLES T" as "\ONG, CHARLES T", "99291" as "992"). Text typed
|
||||
// blur (that is exactly how four fields of one record got saved mid-keystroke:
|
||||
// "Doe, Jane A" as "\e, Jane A", "99291" as "992"). Text typed
|
||||
// into a field is held until an explicit Save, keyed by row_id rather than
|
||||
// bare field name — a bare name repeats once a page can carry more than one
|
||||
// row per field (Gulf Coast's repeated CPT lines), and DemographyTab.tsx
|
||||
// row per field (Example Client's repeated CPT lines), and DemographyTab.tsx
|
||||
// hit exactly this before switching its own drafts to row_id.
|
||||
const [drafts, setDrafts] = useState<Record<number, string>>({})
|
||||
const qc = useQueryClient()
|
||||
@@ -238,7 +239,7 @@ export function ReviewPane({
|
||||
|
||||
// PDF order: page, then where the patient sits on it. line_index is each
|
||||
// record's position on its page, set by build_field_rows. Sorting by name
|
||||
// here used to put ANDERSON above the first patient on the sheet, so the
|
||||
// here used to put a later surname above the first patient on the sheet, so the
|
||||
// list no longer matched the document the reviewer had open beside it.
|
||||
// Name is only the tie-break, for runs stored before line_index existed.
|
||||
return [...byKey.values()].sort(
|
||||
@@ -254,7 +255,7 @@ export function ReviewPane({
|
||||
map.get(key)!.push(row)
|
||||
}
|
||||
for (const rows of map.values()) {
|
||||
// Gulf Coast (Template 7) records keep the order the API sent — the flat
|
||||
// Example Client (Template 7) records keep the order the API sent — the flat
|
||||
// 20-column superbill layout, Ticket# through Units. Re-sorting by band
|
||||
// would scatter it (that is what put ICD11 above ICD2 and CPT at the
|
||||
// bottom). Every other template keeps worst-band-last, which is what the
|
||||
@@ -280,7 +281,7 @@ export function ReviewPane({
|
||||
// A field that was never queued (needs_review === false) has no review
|
||||
// row until this moment on most templates — build_field_rows only emits
|
||||
// a row when a value exists or the field is billing-critical, so a
|
||||
// genuinely blank optional field (e.g. Gulf Coast's From DOS / To DOS /
|
||||
// genuinely blank optional field (e.g. Example Client's From DOS / To DOS /
|
||||
// Units, always null today) is addressed by the cell it occupies,
|
||||
// line_index included, rather than by row_id.
|
||||
if (row.needs_review === false) {
|
||||
@@ -363,7 +364,7 @@ export function ReviewPane({
|
||||
const discardAll = () => setDrafts(settledMap)
|
||||
|
||||
// Leaving a patient with typed-but-unsaved edits used to be silent — the old
|
||||
// blur handler saved automatically, which is what produced the ARMSTRONG
|
||||
// blur handler saved automatically, which is what produced the truncated-name
|
||||
// corruption. Now nothing commits without Save, so leaving instead has to
|
||||
// ask, or the edit is just lost with no signal either way.
|
||||
const guardLeave = (): boolean => {
|
||||
@@ -711,7 +712,7 @@ function PatientView({
|
||||
<div className="flex flex-col gap-[9px]">
|
||||
{/* Keyed on row_id — a real database identity from /all-fields
|
||||
(SPB_Extraction.RowId), unique across every field on every page.
|
||||
A page-and-field key would collide on Gulf Coast's repeated CPT
|
||||
A page-and-field key would collide on Example Client's repeated CPT
|
||||
lines, where two rows share the same (page, field). */}
|
||||
{/* No entry animation. Rows are keyed by row_id, so every Next
|
||||
remounts them all, and the old staggered fade (opacity 0 over
|
||||
@@ -802,7 +803,7 @@ function PatientView({
|
||||
* lost by making it editable.
|
||||
*
|
||||
* Nothing here commits on its own. An earlier version saved on blur, which is
|
||||
* exactly how "ARMSTRONG, CHARLES T" got recorded as "\ONG, CHARLES T" — the
|
||||
* exactly how "Doe, Jane A" got recorded as "\e, Jane A" — the
|
||||
* moment focus left the box mid-keystroke, whatever half-typed text was there
|
||||
* became the correction. Typing only updates the shared draft in ReviewPane;
|
||||
* the patient-level Save bar (here and in PdfPane) is the one place an edit is
|
||||
@@ -835,7 +836,7 @@ function FieldRow({
|
||||
const corrected = row.corrected_value != null && row.corrected_value !== row.value
|
||||
// While being edited the value takes its own full-width line. A DX field is
|
||||
// five comma-separated codes and a provider name runs past twenty
|
||||
// characters; in the shared row they were truncated to "ARMSTRONG, C", so a
|
||||
// characters; in the shared row they were truncated to "Doe, J", so a
|
||||
// reviewer was correcting a value they could not fully see. Expanding only
|
||||
// on focus keeps the scan-many-fields-fast layout for reading.
|
||||
const expanded = focused || dirty
|
||||
@@ -938,7 +939,7 @@ function FieldRow({
|
||||
|
||||
|
||||
/**
|
||||
* A Gulf Coast ticket laid out the way its yellow note is: the note itself,
|
||||
* A Example Client ticket laid out the way its yellow note is: the note itself,
|
||||
* the page-level rules it fired, the visit, then one tab per encounter.
|
||||
*
|
||||
* Hovering a field lights the note line it came from. The page preview is an
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
/* EXAMPLE ONLY: an extract from the Superbill Review prototype, kept as reference for porting. ECW/eClinicalWorks, Tebra, 'Example Client', SPB_* tables and patient/ticket wording are that project's examples. Don't copy them into a new project. */
|
||||
import { useMemo, useState } from 'react'
|
||||
import { useQuery } from '@tanstack/react-query'
|
||||
import { api } from '../api'
|
||||
@@ -95,7 +96,7 @@ type Filter = 'all' | 'priced' | 'unmeasured' | 'failed'
|
||||
|
||||
/**
|
||||
* api.roi() has no project filter — it totals every document. The ROI board
|
||||
* is per-project (Gulf Coast's spend is not eClinicalWorks' spend), so the
|
||||
* is per-project (Example Client's spend is not eClinicalWorks' spend), so the
|
||||
* totals are recomputed here from the already-fetched runs instead of a new
|
||||
* query param. Every field is a plain sum or count over RoiRun — nothing
|
||||
* server-side is being second-guessed, just re-scoped to fewer rows.
|
||||
@@ -138,7 +139,7 @@ export function RoiTab({
|
||||
}: {
|
||||
/** Absent on the demography board: its runs have no charge review to open. */
|
||||
onOpenRun?: (jobId: string) => void
|
||||
/** Which project's spend this board reports — Gulf Coast tickets and
|
||||
/** Which project's spend this board reports — Example Client tickets and
|
||||
* eClinicalWorks documents never share a total. */
|
||||
project: Project
|
||||
/** The Demography ROI (ticket 05): its own payload, one Gemini call per PDF
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
/* EXAMPLE ONLY: an extract from the Superbill Review prototype, kept as reference for porting. ECW/eClinicalWorks, Tebra, 'Example Client', SPB_* tables and patient/ticket wording are that project's examples. Don't copy them into a new project. */
|
||||
import { useMutation, useQuery, useQueryClient } from '@tanstack/react-query'
|
||||
import { api } from '../api'
|
||||
import { IconDownload } from './icons'
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
/* EXAMPLE ONLY: an extract from the Superbill Review prototype, kept as reference for porting. ECW/eClinicalWorks, Tebra, 'Example Client', SPB_* tables and patient/ticket wording are that project's examples. Don't copy them into a new project. */
|
||||
import { useState } from 'react'
|
||||
import type { ReactElement } from 'react'
|
||||
import type { BatchStage, BoardTab } from '../types'
|
||||
@@ -14,7 +15,7 @@ import { IconSpend, IconPage, IconLoop, IconIdCard, IconPatients } from './icons
|
||||
* icons are" step from every navigation.
|
||||
*
|
||||
* Two projects, one rail: ECW's boards (templates 1-6) and Tebra's (template 7
|
||||
* / Gulf Coast), each under its own group header. See project.ts for how a
|
||||
* / Example Client), each under its own group header. See project.ts for how a
|
||||
* batch or run is assigned to one or the other.
|
||||
*
|
||||
* Selection and drag-and-drop-to-move-stage behaviour are unchanged — only the
|
||||
@@ -136,7 +137,7 @@ export function Sidebar({
|
||||
tab="tebra-roi"
|
||||
icon={IconSpend}
|
||||
label="ROI Dashboard"
|
||||
hint="What the Gulf Coast pipeline has cost, and what that bought"
|
||||
hint="What the Example Client pipeline has cost, and what that bought"
|
||||
active={tab === 'tebra-roi'}
|
||||
onSelect={onTab}
|
||||
/>
|
||||
@@ -146,8 +147,8 @@ export function Sidebar({
|
||||
dropStage="extraction"
|
||||
dropTab="tebra-extraction"
|
||||
icon={IconPage}
|
||||
label="Gulf Coast Charge Extraction"
|
||||
hint="Gulf Coast tickets: extract and clear the flagged fields"
|
||||
label="Example Client Charge Extraction"
|
||||
hint="Example Client tickets: extract and clear the flagged fields"
|
||||
active={tab === 'tebra-extraction'}
|
||||
n={counts.tebra.extraction}
|
||||
onSelect={onTab}
|
||||
@@ -159,8 +160,8 @@ export function Sidebar({
|
||||
dropStage="automation"
|
||||
dropTab="tebra-automation"
|
||||
icon={IconLoop}
|
||||
label="Gulf Coast Charge Automation"
|
||||
hint="Gulf Coast batches that finished extraction and are ready to post"
|
||||
label="Example Client Charge Automation"
|
||||
hint="Example Client batches that finished extraction and are ready to post"
|
||||
active={tab === 'tebra-automation'}
|
||||
n={counts.tebra.automation}
|
||||
onSelect={onTab}
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
/* EXAMPLE ONLY: an extract from the Superbill Review prototype, kept as reference for porting. ECW/eClinicalWorks, Tebra, 'Example Client', SPB_* tables and patient/ticket wording are that project's examples. Don't copy them into a new project. */
|
||||
import { useCallback, useEffect, useRef, useState } from 'react'
|
||||
|
||||
const KEY = 'superbill.split'
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
/* EXAMPLE ONLY: an extract from the Superbill Review prototype, kept as reference for porting. ECW/eClinicalWorks, Tebra, 'Example Client', SPB_* tables and patient/ticket wording are that project's examples. Don't copy them into a new project. */
|
||||
import { BAND_VAR } from '../bands'
|
||||
import type { Run } from '../types'
|
||||
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
/* EXAMPLE ONLY: an extract from the Superbill Review prototype, kept as reference for porting. ECW/eClinicalWorks, Tebra, 'Example Client', SPB_* tables and patient/ticket wording are that project's examples. Don't copy them into a new project. */
|
||||
import { useEffect, useLayoutEffect, useRef, useState } from 'react'
|
||||
import { createPortal } from 'react-dom'
|
||||
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
/* EXAMPLE ONLY: an extract from the Superbill Review prototype, kept as reference for porting. ECW/eClinicalWorks, Tebra, 'Example Client', SPB_* tables and patient/ticket wording are that project's examples. Don't copy them into a new project. */
|
||||
/**
|
||||
* The icon set.
|
||||
*
|
||||
|
||||
Reference in new issue
Block a user