@mindbill/react 0.17.0 → 0.18.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -8,18 +8,15 @@ npm install @mindbill/react @mindbill/node
8
8
 
9
9
  ## Connected lifecycle
10
10
 
11
- `ConnectedBillLifecycle` is the default integration. It owns bill loading, payer lookup, editable review, attachments, submission, status refresh, EORs, payment posting, Second Bill Review, correction/resubmission, and close.
12
-
13
- Procedure entry is keyboard-first: the form always keeps one empty row after the entered lines, grows as soon as that row is partially filled, and omits the empty row from save and submit payloads.
11
+ `ConnectedBillLifecycle` starts after your server atomically creates and submits an immutable bill. It owns bill loading, status refresh, EORs, payment posting, Second Bill Review, and close.
14
12
 
15
13
  ```tsx
16
14
  import { ConnectedBillLifecycle } from "@mindbill/react";
17
15
 
18
16
  <ConnectedBillLifecycle
19
- create={knownBillValues}
17
+ billId={billId}
20
18
  sessionEndpoint="/api/mindbill/session"
21
19
  appearance={{ preset: "qme-companion" }}
22
- onBillCreated={(billId) => navigate(`/bills/${billId}`)}
23
20
  />
24
21
  ```
25
22
 
@@ -64,8 +61,6 @@ export async function POST(request: Request) {
64
61
  }
65
62
  ```
66
63
 
67
- The component searches MindBill's claims-administrator directory with both payer text and the current claim number. It explains name and claim-pattern evidence, shows delivery availability, and only preselects a high-confidence exact name or alias match.
68
-
69
64
  The API key binds every session to one organization. `subject` identifies the user and `permissions` express the role. MindBill enforces the organization boundary on every bill request. A permanent Partner API key must never enter frontend code.
70
65
 
71
66
  ## Compact status
@@ -98,7 +93,6 @@ import { BillLifecycleActions } from "@mindbill/react";
98
93
  case "view_eor": return bill.openEor();
99
94
  case "post_payment": return setPaymentOpen(true);
100
95
  case "second_review": return setSecondReviewOpen(true);
101
- case "correct_and_resubmit": return bill.startCorrection();
102
96
  case "close": return bill.closeBill({ reason: "Resolved" });
103
97
  }
104
98
  }}
@@ -117,32 +111,31 @@ import { BillActivityTimeline } from "@mindbill/react";
117
111
  <BillActivityTimeline events={billEvents} />
118
112
  ```
119
113
 
120
- Browser callbacks such as `onBillCreated`, `onBillIdChange`, and `onChanged` are for immediate UI, navigation, optimistic state, and analytics. Signed webhooks are the authoritative integration for durable server state.
114
+ Browser callbacks such as `onChanged` are for immediate UI, navigation, optimistic state, and analytics. Signed webhooks are the authoritative integration for durable server state.
115
+
116
+ ## Bill submission form
121
117
 
122
- ## Controlled escape hatch
118
+ `BillSubmissionForm` owns the complete pre-submission experience: the bill field schema, required-field rules and red asterisks, validation, service-line editing, source-document selection, PDF uploads, and the single Submit action. Its `bill` value is structurally identical to the server SDK's `CreateBillRequest`.
123
119
 
124
- Use `BillReviewForm` only when your application intentionally owns the API calls and local review state. Known bill values and payer documents remain explicit and editable.
120
+ The partner application only loads initial values and sends the component's immutable snapshot to its authenticated server route. Uploaded files stay in the browser until the user submits.
125
121
 
126
122
  ```tsx
127
- import { BillReviewForm } from "@mindbill/react";
123
+ import { BillSubmissionForm } from "@mindbill/react";
128
124
 
129
- <BillReviewForm
130
- data={billReview}
125
+ <BillSubmissionForm
126
+ initialBill={bootstrap.bill}
127
+ attachments={bootstrap.attachments}
131
128
  appearance={{ preset: "qme-companion" }}
132
- onSave={(input) => api.patch("/billing/review", input)}
133
- onSubmit={(input, route) => api.post("/billing/submit", { input, route })}
134
- onAddAttachment={(file, documentType, description) =>
135
- api.upload("/billing/attachments", { file, documentType, description })
136
- }
137
- onRemoveAttachment={(attachmentId) =>
138
- api.delete(`/billing/attachments/${attachmentId}`)
139
- }
140
- onSearchClaimsAdministrators={(query, claimNumber) =>
141
- api.searchPayers({ query, claimNumber })
129
+ onSubmit={({ bill, sourceAttachmentIds, uploads }) =>
130
+ submitBill({ bill, sourceAttachmentIds, uploads })
142
131
  }
143
132
  />
144
133
  ```
145
134
 
135
+ `BILL_SUBMISSION_REQUIRED_FIELDS` and `validateBillSubmission` expose the same contract for tests and non-visual integrations. The component never creates a draft; its callback fires only when the user submits a locally valid snapshot.
136
+
137
+ `BillReviewForm` remains available for legacy integrations that already own a custom review model. New integrations should use `BillSubmissionForm`.
138
+
146
139
  Use `BillStatusSummary` only when your application already owns status loading and wants a presentation-only component:
147
140
 
148
141
  ```tsx
package/dist/index.d.ts CHANGED
@@ -1,8 +1,8 @@
1
1
  import { MindBillAppearance, MindBillEventDetail, MindBillErrorDetail } from '@mindbill/embed';
2
2
  export { MindBillAppearance, MindBillErrorDetail, MindBillEventDetail } from '@mindbill/embed';
3
3
  import { CSSProperties, ReactElement, ReactNode } from 'react';
4
- import { BillLifecycleAction, BillLifecycleDelivery, BillPaymentRecord, BillRemittanceSummary, BillLifecycleData, BillLifecycleClientOptions, BrowserBillCreateInput, BillLifecycleClient, BillEorDocument } from '@mindbill/browser';
5
- export { BillActivityRecord, BillEorDocument, BillLifecycleAction, BillLifecycleActionId, BillLifecycleClient, BillLifecycleClientOptions, BillLifecycleData, BillLifecycleDelivery, BillLifecycleSession, BillLifecycleSessionProvider, BillLifecycleSessionRequest, BillPaymentRecord, BillRemittanceSummary, BrowserBillAddress, BrowserBillCreateInput, CloseBillInput, PostBillPaymentInput, SubmitSecondReviewInput, createBillLifecycleClient } from '@mindbill/browser';
4
+ import { BillLifecycleAction, BillLifecycleDelivery, BillPaymentRecord, BillRemittanceSummary, BillLifecycleData, BillLifecycleClientOptions, BillLifecycleClient, BillEorDocument } from '@mindbill/browser';
5
+ export { BillActivityRecord, BillEorDocument, BillLifecycleAction, BillLifecycleActionId, BillLifecycleClient, BillLifecycleClientOptions, BillLifecycleData, BillLifecycleDelivery, BillLifecycleSession, BillLifecycleSessionProvider, BillLifecycleSessionRequest, BillPaymentRecord, BillRemittanceSummary, CloseBillInput, PostBillPaymentInput, SubmitSecondReviewInput, createBillLifecycleClient } from '@mindbill/browser';
6
6
 
7
7
  type MindBillThemePreset = "mindbill" | "qme-companion" | "orange-bright" | "clinical-blue";
8
8
  type MindBillReactAppearance = MindBillAppearance & {
@@ -273,7 +273,7 @@ type BillDeliveryOptions = {
273
273
  mailingAddress?: string | null;
274
274
  };
275
275
  };
276
- type BillSubmissionInput = {
276
+ type BillSubmissionInput$1 = {
277
277
  route: BillSubmissionRoute;
278
278
  destination?: {
279
279
  faxNumber?: string;
@@ -286,9 +286,11 @@ type BillSubmissionInput = {
286
286
  };
287
287
  type BillReviewFormProps = {
288
288
  data: BillReviewData;
289
- onSave: (input: BillReviewSaveInput) => Promise<BillReviewData | void>;
290
- onSubmit: (input: BillReviewSaveInput, submission: BillSubmissionInput) => Promise<void>;
291
- onGetDeliveryOptions: () => Promise<BillDeliveryOptions>;
289
+ mode?: "review" | "submission";
290
+ initialSubmission?: BillSubmissionInput$1;
291
+ onSave?: (input: BillReviewSaveInput) => Promise<BillReviewData | void>;
292
+ onSubmit: (input: BillReviewSaveInput, submission: BillSubmissionInput$1) => Promise<void>;
293
+ onGetDeliveryOptions?: () => Promise<BillDeliveryOptions>;
292
294
  onAddAttachment: (file: File, documentType: BillReviewDocumentType, description?: string) => Promise<void>;
293
295
  onRemoveAttachment: (attachmentId: string) => Promise<void>;
294
296
  onOpenAttachment?: (attachment: BillReviewAttachment) => void;
@@ -321,7 +323,7 @@ type BillReviewDraft = {
321
323
  lineItems: BillReviewLineItem[];
322
324
  };
323
325
  declare function buildBillReviewSaveInput(draft: BillReviewDraft): BillReviewSaveInput;
324
- declare function BillReviewForm({ data, onSave, onSubmit, onGetDeliveryOptions, onAddAttachment, onRemoveAttachment, onOpenAttachment, onSearchClaimsAdministrators, className, style, appearance, features, disabled, }: BillReviewFormProps): ReactElement;
326
+ declare function BillReviewForm({ data, mode, initialSubmission, onSave, onSubmit, onGetDeliveryOptions, onAddAttachment, onRemoveAttachment, onOpenAttachment, onSearchClaimsAdministrators, className, style, appearance, features, disabled, }: BillReviewFormProps): ReactElement;
325
327
  type BillStatusSummaryProps = {
326
328
  status: string;
327
329
  submittedAt?: string | null;
@@ -344,6 +346,118 @@ type BillStatusAction = {
344
346
  };
345
347
  declare function BillStatusSummary({ status, submittedAt, agingDays, updatedAt, totalCharge, totalPaid, balanceDue, actions, className, style, appearance }: BillStatusSummaryProps): ReactElement;
346
348
 
349
+ declare const BILL_SUBMISSION_DOCUMENT_TYPES: readonly ["final_report", "proof_of_service", "letter_of_attestation", "form_122", "return_to_work_voucher", "w9", "medical_records", "appeal", "other"];
350
+ type BillSubmissionDocumentType = (typeof BILL_SUBMISSION_DOCUMENT_TYPES)[number];
351
+ type BillSubmissionAddress = {
352
+ line1: string;
353
+ city: string;
354
+ state: string;
355
+ postalCode: string;
356
+ };
357
+ type BillSubmissionInput = {
358
+ externalId?: string;
359
+ billingMode?: "med_legal" | "professional";
360
+ patient: {
361
+ id?: string;
362
+ externalId?: string;
363
+ firstName: string;
364
+ middleName?: string;
365
+ lastName: string;
366
+ dateOfBirth?: string;
367
+ ssn?: string;
368
+ gender?: "M" | "F" | "X";
369
+ phone?: string;
370
+ address: BillSubmissionAddress;
371
+ };
372
+ claim: {
373
+ id?: string;
374
+ externalId?: string;
375
+ claimNumber: string;
376
+ adjNumber?: string;
377
+ employer?: string;
378
+ dateOfInjury?: string;
379
+ injuryState?: string;
380
+ description?: string;
381
+ claimsAdministrator?: {
382
+ id?: string;
383
+ name: string;
384
+ };
385
+ };
386
+ service: {
387
+ date: string;
388
+ endDate?: string | null;
389
+ authorizationNumber?: string | null;
390
+ };
391
+ billingProvider?: {
392
+ name?: string;
393
+ taxId?: string;
394
+ npi?: string;
395
+ phone?: string;
396
+ address?: BillSubmissionAddress;
397
+ };
398
+ renderingProvider?: {
399
+ name?: string;
400
+ specialty?: string;
401
+ npi?: string;
402
+ taxonomy?: string;
403
+ licenseNumber?: string;
404
+ licenseState?: string;
405
+ isQme?: boolean;
406
+ isAme?: boolean;
407
+ };
408
+ serviceLocation?: {
409
+ name?: string;
410
+ address?: BillSubmissionAddress;
411
+ placeOfServiceCode?: string;
412
+ };
413
+ diagnoses?: string[];
414
+ serviceLines: Array<{
415
+ code: string;
416
+ modifiers?: string[];
417
+ units?: number;
418
+ serviceDate?: string;
419
+ serviceDateEnd?: string | null;
420
+ charge?: number;
421
+ diagnosisPointers?: number[];
422
+ }>;
423
+ };
424
+ type BillSubmissionSourceAttachment = {
425
+ id: string;
426
+ fileName: string;
427
+ documentType: BillSubmissionDocumentType;
428
+ description?: string;
429
+ selected?: boolean;
430
+ };
431
+ type BillSubmissionUpload = {
432
+ file: File;
433
+ documentType: BillSubmissionDocumentType;
434
+ description?: string;
435
+ };
436
+ type BillSubmissionFormValue = {
437
+ bill: BillSubmissionInput;
438
+ sourceAttachmentIds: string[];
439
+ uploads: BillSubmissionUpload[];
440
+ };
441
+ type BillSubmissionFormProps = {
442
+ initialBill: BillSubmissionInput;
443
+ attachments?: BillSubmissionSourceAttachment[];
444
+ onSubmit: (value: BillSubmissionFormValue) => void | Promise<void>;
445
+ appearance?: MindBillReactAppearance;
446
+ className?: string;
447
+ style?: CSSProperties;
448
+ disabled?: boolean;
449
+ submitLabel?: string;
450
+ heading?: ReactNode;
451
+ description?: ReactNode;
452
+ };
453
+ declare const BILL_SUBMISSION_REQUIRED_FIELDS: readonly ["patient.firstName", "patient.lastName", "patient.address.line1", "patient.address.city", "patient.address.state", "patient.address.postalCode", "claim.claimNumber", "service.date", "serviceLines[].code", "serviceLines[].units"];
454
+ type BillSubmissionValidation = {
455
+ valid: boolean;
456
+ fieldErrors: Record<string, string>;
457
+ };
458
+ declare function validateBillSubmission(bill: BillSubmissionInput): BillSubmissionValidation;
459
+ declare function BillSubmissionForm({ initialBill, attachments, onSubmit, appearance, className, style, disabled, submitLabel, heading, description, }: BillSubmissionFormProps): ReactElement;
460
+
347
461
  type BillStatusData = {
348
462
  billId: string;
349
463
  state: string;
@@ -463,16 +577,12 @@ type BillPaymentLedgerProps = SurfaceProps & {
463
577
  declare function BillPaymentLedger({ payments, appearance, className, style }: BillPaymentLedgerProps): ReactElement;
464
578
 
465
579
  type UseBillLifecycleOptions = BillLifecycleClientOptions & {
466
- /** Initial bill snapshot used when no existing `billId` is supplied. */
467
- create?: BrowserBillCreateInput;
468
580
  refreshInterval?: number;
469
581
  enabled?: boolean;
470
582
  initialData?: BillLifecycleData | null;
471
- onBillCreated?: (billId: string, data: BillLifecycleData) => void | Promise<void>;
472
- onBillIdChange?: (billId: string, previousBillId: string | null) => void | Promise<void>;
473
583
  };
474
584
  type UseBillLifecycleResult = {
475
- billId: string | null;
585
+ billId: string;
476
586
  data: BillLifecycleData | null;
477
587
  error: Error | null;
478
588
  isLoading: boolean;
@@ -481,28 +591,22 @@ type UseBillLifecycleResult = {
481
591
  refresh: () => Promise<void>;
482
592
  searchClaimsAdministrators: BillLifecycleClient["searchClaimsAdministrators"];
483
593
  getDeliveryOptions: BillLifecycleClient["getDeliveryOptions"];
484
- saveReview: BillLifecycleClient["saveReview"];
485
- submitBill: BillLifecycleClient["submitBill"];
486
- addAttachment: BillLifecycleClient["addAttachment"];
487
- removeAttachment: BillLifecycleClient["removeAttachment"];
488
594
  openAttachment: (attachment: BillReviewAttachment) => Promise<void>;
489
595
  openEor: (document: BillEorDocument) => Promise<void>;
490
596
  closeBill: BillLifecycleClient["closeBill"];
491
597
  postPayment: BillLifecycleClient["postPayment"];
492
598
  submitSecondReview: BillLifecycleClient["submitSecondReview"];
493
- startCorrection: () => Promise<BillLifecycleData>;
494
599
  };
495
- declare function useBillLifecycle({ billId: providedBillId, create, sessionEndpoint, getSession, apiBaseUrl, refreshInterval, enabled, initialData, onBillCreated, onBillIdChange, fetch: fetchOverride, }: UseBillLifecycleOptions): UseBillLifecycleResult;
600
+ declare function useBillLifecycle({ billId: providedBillId, sessionEndpoint, getSession, apiBaseUrl, refreshInterval, enabled, initialData, fetch: fetchOverride, }: UseBillLifecycleOptions): UseBillLifecycleResult;
496
601
  type ConnectedBillLifecycleProps = UseBillLifecycleOptions & {
497
602
  appearance?: MindBillReactAppearance;
498
- features?: BillReviewFeatures;
499
603
  className?: string;
500
604
  style?: CSSProperties;
501
605
  loadingFallback?: ReactNode;
502
606
  errorFallback?: (error: Error, retry: () => Promise<void>) => ReactNode;
503
607
  onChanged?: (data: BillLifecycleData) => void;
504
608
  };
505
- declare function ConnectedBillLifecycle({ appearance, features, className, style, loadingFallback, errorFallback, onChanged, ...options }: ConnectedBillLifecycleProps): ReactElement;
609
+ declare function ConnectedBillLifecycle({ appearance, className, style, loadingFallback, errorFallback, onChanged, ...options }: ConnectedBillLifecycleProps): ReactElement;
506
610
 
507
611
  type MindBillWidgetProps = {
508
612
  sessionToken: string;
@@ -516,4 +620,4 @@ type MindBillWidgetProps = {
516
620
  declare function MindBillBillTimeline(props: MindBillWidgetProps): ReactElement;
517
621
  declare function MindBillBillReview(props: MindBillWidgetProps): ReactElement;
518
622
 
519
- export { type BillActivityEvent, BillActivityTimeline, type BillActivityTimelineProps, BillLifecycleActions, type BillLifecycleActionsProps, BillLifecycleProgress, type BillLifecycleProgressProps, type BillLifecycleStage, BillPayerContactCard, type BillPayerContactCardProps, BillPaymentLedger, type BillPaymentLedgerProps, BillRemittanceCard, type BillRemittanceCardProps, type BillReviewAttachment, type BillReviewBillingProvider, type BillReviewClinician, type BillReviewData, type BillReviewDocumentType, type BillReviewDraft, type BillReviewFeatures, BillReviewForm, type BillReviewFormProps, type BillReviewLineItem, type BillReviewLocation, type BillReviewPayer, type BillReviewSaveInput, BillSnapshotSummary, type BillSnapshotSummaryProps, type BillStatusAction, type BillStatusClient, type BillStatusClientOptions, type BillStatusData, type BillStatusSession, type BillStatusSessionProvider, type BillStatusSessionRequest, BillStatusSummary, type BillStatusSummaryProps, type BillSubmissionRoute, ConnectedBillLifecycle, type ConnectedBillLifecycleProps, ConnectedBillStatus, type ConnectedBillStatusProps, MindBillBillReview, MindBillBillTimeline, type MindBillReactAppearance, type MindBillThemePreset, type MindBillWidgetProps, type UseBillLifecycleOptions, type UseBillLifecycleResult, type UseBillStatusOptions, type UseBillStatusResult, billActivityEventLabel, billLifecycleStage, buildBillReviewSaveInput, createBillStatusClient, ensureTrailingProcedureLine, mindBillAppearanceStyle, mindBillThemePresets, resolveMindBillAppearance, useBillLifecycle, useBillStatus, visibleBillLifecycleActions };
623
+ export { BILL_SUBMISSION_DOCUMENT_TYPES, BILL_SUBMISSION_REQUIRED_FIELDS, type BillActivityEvent, BillActivityTimeline, type BillActivityTimelineProps, BillLifecycleActions, type BillLifecycleActionsProps, BillLifecycleProgress, type BillLifecycleProgressProps, type BillLifecycleStage, BillPayerContactCard, type BillPayerContactCardProps, BillPaymentLedger, type BillPaymentLedgerProps, BillRemittanceCard, type BillRemittanceCardProps, type BillReviewAttachment, type BillReviewBillingProvider, type BillReviewClinician, type BillReviewData, type BillReviewDocumentType, type BillReviewDraft, type BillReviewFeatures, BillReviewForm, type BillReviewFormProps, type BillReviewLineItem, type BillReviewLocation, type BillReviewPayer, type BillReviewSaveInput, BillSnapshotSummary, type BillSnapshotSummaryProps, type BillStatusAction, type BillStatusClient, type BillStatusClientOptions, type BillStatusData, type BillStatusSession, type BillStatusSessionProvider, type BillStatusSessionRequest, BillStatusSummary, type BillStatusSummaryProps, type BillSubmissionAddress, type BillSubmissionDocumentType, BillSubmissionForm, type BillSubmissionFormProps, type BillSubmissionFormValue, type BillSubmissionInput, type BillSubmissionRoute, type BillSubmissionSourceAttachment, type BillSubmissionUpload, type BillSubmissionValidation, ConnectedBillLifecycle, type ConnectedBillLifecycleProps, ConnectedBillStatus, type ConnectedBillStatusProps, MindBillBillReview, MindBillBillTimeline, type MindBillReactAppearance, type MindBillThemePreset, type MindBillWidgetProps, type UseBillLifecycleOptions, type UseBillLifecycleResult, type UseBillStatusOptions, type UseBillStatusResult, billActivityEventLabel, billLifecycleStage, buildBillReviewSaveInput, createBillStatusClient, ensureTrailingProcedureLine, mindBillAppearanceStyle, mindBillThemePresets, resolveMindBillAppearance, useBillLifecycle, useBillStatus, validateBillSubmission, visibleBillLifecycleActions };