Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
35 changes: 23 additions & 12 deletions apps/dashboard/src/api/generated/analysis/analysis.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ import type {
} from '@tanstack/react-query';

import type {
AnalyzeAnalyzePostParams,
AnalyzeRequest,
AnalyzeWithDocumentsAnalyzeWithDocumentsPostParams,
BodyAnalyzeWithDocumentsAnalyzeWithDocumentsPost,
Expand All @@ -36,6 +37,8 @@ import type {
* Analyze clinical data and generate PA form response.

Uses LLM to extract evidence from clinical data and generate PA form.
Resolves policy from registry; unknown CPT codes fall back to generic policy.
When demo=True and procedure_code is 72148, returns a canned demo response.
* @summary Analyze
*/
export type analyzeAnalyzePostResponse200 = {
Expand All @@ -57,17 +60,25 @@ export type analyzeAnalyzePostResponseError = (analyzeAnalyzePostResponse422) &

export type analyzeAnalyzePostResponse = (analyzeAnalyzePostResponseSuccess | analyzeAnalyzePostResponseError)

export const getAnalyzeAnalyzePostUrl = () => {
export const getAnalyzeAnalyzePostUrl = (params?: AnalyzeAnalyzePostParams,) => {
const normalizedParams = new URLSearchParams();

Object.entries(params || {}).forEach(([key, value]) => {

if (value !== undefined) {
normalizedParams.append(key, value === null ? 'null' : value.toString())
}
});


const stringifiedParams = normalizedParams.toString();

return `http://localhost:8000/analyze`
return stringifiedParams.length > 0 ? `http://localhost:8000/analyze?${stringifiedParams}` : `http://localhost:8000/analyze`
}

export const analyzeAnalyzePost = async (analyzeRequest: AnalyzeRequest, options?: RequestInit): Promise<analyzeAnalyzePostResponse> => {
export const analyzeAnalyzePost = async (analyzeRequest: AnalyzeRequest,
params?: AnalyzeAnalyzePostParams, options?: RequestInit): Promise<analyzeAnalyzePostResponse> => {

const res = await fetch(getAnalyzeAnalyzePostUrl(),
const res = await fetch(getAnalyzeAnalyzePostUrl(params),
{
...options,
method: 'POST',
Expand All @@ -87,8 +98,8 @@ export const analyzeAnalyzePost = async (analyzeRequest: AnalyzeRequest, options


export const getAnalyzeAnalyzePostMutationOptions = <TError = HTTPValidationError,
TContext = unknown>(options?: { mutation?:UseMutationOptions<Awaited<ReturnType<typeof analyzeAnalyzePost>>, TError,{data: AnalyzeRequest}, TContext>, fetch?: RequestInit}
): UseMutationOptions<Awaited<ReturnType<typeof analyzeAnalyzePost>>, TError,{data: AnalyzeRequest}, TContext> => {
TContext = unknown>(options?: { mutation?:UseMutationOptions<Awaited<ReturnType<typeof analyzeAnalyzePost>>, TError,{data: AnalyzeRequest;params?: AnalyzeAnalyzePostParams}, TContext>, fetch?: RequestInit}
): UseMutationOptions<Awaited<ReturnType<typeof analyzeAnalyzePost>>, TError,{data: AnalyzeRequest;params?: AnalyzeAnalyzePostParams}, TContext> => {

const mutationKey = ['analyzeAnalyzePost'];
const {mutation: mutationOptions, fetch: fetchOptions} = options ?
Expand All @@ -100,10 +111,10 @@ const {mutation: mutationOptions, fetch: fetchOptions} = options ?



const mutationFn: MutationFunction<Awaited<ReturnType<typeof analyzeAnalyzePost>>, {data: AnalyzeRequest}> = (props) => {
const {data} = props ?? {};
const mutationFn: MutationFunction<Awaited<ReturnType<typeof analyzeAnalyzePost>>, {data: AnalyzeRequest;params?: AnalyzeAnalyzePostParams}> = (props) => {
const {data,params} = props ?? {};

return analyzeAnalyzePost(data,fetchOptions)
return analyzeAnalyzePost(data,params,fetchOptions)
}


Expand All @@ -119,11 +130,11 @@ const {mutation: mutationOptions, fetch: fetchOptions} = options ?
* @summary Analyze
*/
export const useAnalyzeAnalyzePost = <TError = HTTPValidationError,
TContext = unknown>(options?: { mutation?:UseMutationOptions<Awaited<ReturnType<typeof analyzeAnalyzePost>>, TError,{data: AnalyzeRequest}, TContext>, fetch?: RequestInit}
TContext = unknown>(options?: { mutation?:UseMutationOptions<Awaited<ReturnType<typeof analyzeAnalyzePost>>, TError,{data: AnalyzeRequest;params?: AnalyzeAnalyzePostParams}, TContext>, fetch?: RequestInit}
): UseMutationResult<
Awaited<ReturnType<typeof analyzeAnalyzePost>>,
TError,
{data: AnalyzeRequest},
{data: AnalyzeRequest;params?: AnalyzeAnalyzePostParams},
TContext
> => {

Expand Down
23 changes: 23 additions & 0 deletions apps/dashboard/src/api/generated/intelligence.schemas.ts
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,8 @@ export const EvidenceItemStatus = {
export interface EvidenceItem {
/** ID of the policy criterion */
criterion_id: string;
/** Human-readable criterion label */
criterion_label?: string;
/** Criterion status */
status: EvidenceItemStatus;
/** Extracted evidence text */
Expand Down Expand Up @@ -81,6 +83,16 @@ export const PAFormResponseRecommendation = {
*/
export type PAFormResponseFieldMappings = {[key: string]: string};

/**
* Policy identifier
*/
export type PAFormResponsePolicyId = string | null;

/**
* LCD article reference
*/
export type PAFormResponseLcdReference = string | null;

/**
* Complete PA form response from analysis.
*/
Expand Down Expand Up @@ -109,6 +121,10 @@ export interface PAFormResponse {
confidence_score: number;
/** PDF field name to value mappings */
field_mappings: PAFormResponseFieldMappings;
/** Policy identifier */
policy_id?: PAFormResponsePolicyId;
/** LCD article reference */
lcd_reference?: PAFormResponseLcdReference;
}

export type ValidationErrorLocItem = string | number;
Expand All @@ -119,6 +135,13 @@ export interface ValidationError {
type: string;
}

export type AnalyzeAnalyzePostParams = {
/**
* Return canned demo response for supported procedures
*/
demo?: boolean;
};

export type AnalyzeWithDocumentsAnalyzeWithDocumentsPostParams = {
patient_id: string;
procedure_code: string;
Expand Down
6 changes: 4 additions & 2 deletions apps/dashboard/src/components/__tests__/NewPAModal.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import { describe, it, expect, vi } from 'vitest';
import { QueryClient, QueryClientProvider } from '@tanstack/react-query';
import { NewPAModal } from '../NewPAModal';
import { type Patient } from '../../lib/patients';
import { type Procedure } from '@/api/graphqlService';

// Mock TanStack Router
vi.mock('@tanstack/react-router', () => ({
Expand Down Expand Up @@ -48,10 +49,11 @@ const mockPatient: Patient = {
phone: '(253) 555-0654',
};

const mockService = {
const mockService: Procedure = {
code: '72148',
name: 'MRI Lumbar Spine',
type: 'procedure' as const,
category: 'Imaging',
requiresPA: true,
};

describe('NewPAModal', () => {
Expand Down
28 changes: 28 additions & 0 deletions apps/dashboard/src/components/ehr/EhrHeader.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,11 @@ interface EhrHeaderPatient {
name: string;
dob: string;
mrn: string;
age?: number;
sex?: 'M' | 'F';
insurance?: string;
memberId?: string;
allergies?: string[];
}

interface EncounterMeta {
Expand Down Expand Up @@ -41,12 +46,35 @@ export function EhrHeader({ patient, encounterMeta }: EhrHeaderProps) {
<div className="flex items-center gap-6">
<span className="text-base font-bold text-gray-900">{patient.name}</span>
<div className="flex items-center gap-4 text-sm text-gray-600">
{patient.age != null && patient.sex && (
<span>{patient.age}{patient.sex}</span>
)}
<span>
<span className="font-medium text-gray-500">DOB:</span> {patient.dob}
</span>
<span>
<span className="font-medium text-gray-500">MRN:</span> {patient.mrn}
</span>
{patient.insurance && (
<>
<span className="text-gray-300">|</span>
<span>
<span className="font-medium text-gray-500">Ins:</span> {patient.insurance}
</span>
{patient.memberId && (
<span className="text-xs text-gray-400">({patient.memberId})</span>
)}
Comment on lines +64 to +66
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor

Add a space before the member ID.

These adjacent inline spans currently render as ...Blue Cross Blue Shield(ATH60182) because there is no whitespace between them.

✏️ Minimal fix
-                {patient.memberId && (
-                  <span className="text-xs text-gray-400">({patient.memberId})</span>
-                )}
+                {patient.memberId && (
+                  <span className="text-xs text-gray-400"> ({patient.memberId})</span>
+                )}
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
{patient.memberId && (
<span className="text-xs text-gray-400">({patient.memberId})</span>
)}
{patient.memberId && (
<span className="text-xs text-gray-400"> ({patient.memberId})</span>
)}
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@apps/dashboard/src/components/ehr/EhrHeader.tsx` around lines 64 - 66, The
member ID span is rendered without a leading space causing adjacent text to run
together; update the JSX where patient.memberId is checked (the block containing
"{patient.memberId && ( <span className=...>({patient.memberId})</span> )}") to
include a visible space before the "(" — e.g., add a regular space or a
non‑breaking space character before the parenthesis in that span so the output
becomes " (ATH60182)".

</>
)}
{patient.allergies && patient.allergies.length > 0 && (
<>
<span className="text-gray-300">|</span>
<span className="text-red-600">
<span className="font-medium">Allergies:</span>{' '}
{patient.allergies.join(', ')}
</span>
</>
)}
</div>
</div>
</div>
Expand Down
Loading
Loading