Implements complete insurance module with: - Insurance company catalog (private, government, HMO, PPO) - Insurance plans with coverage details, deductibles, copays - Patient insurance policies with verification workflow - Insurance claims with full lifecycle (draft->submitted->approved/denied/paid) - Preauthorization requests with approval workflow - Coverage verification endpoint - EOB (Explanation of Benefits) tracking - Aging reports for claims management Entities: InsuranceCompany, InsurancePlan, PatientInsurance, InsuranceClaim, Preauthorization Services: Full CRUD + workflow operations for each entity Controller: 50+ REST endpoints for all insurance operations Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
149 lines
4.1 KiB
TypeScript
149 lines
4.1 KiB
TypeScript
import {
|
|
Entity,
|
|
PrimaryGeneratedColumn,
|
|
Column,
|
|
CreateDateColumn,
|
|
UpdateDateColumn,
|
|
DeleteDateColumn,
|
|
Index,
|
|
ManyToOne,
|
|
JoinColumn,
|
|
OneToMany,
|
|
} from 'typeorm';
|
|
import { InsuranceCompany } from './insurance-company.entity';
|
|
import { PatientInsurance } from './patient-insurance.entity';
|
|
|
|
export type InsurancePlanStatus = 'active' | 'inactive' | 'discontinued';
|
|
export type CoverageType = 'individual' | 'family' | 'group' | 'medicare' | 'medicaid' | 'other';
|
|
|
|
export interface CoverageDetails {
|
|
consultations?: number;
|
|
hospitalizations?: number;
|
|
emergencies?: number;
|
|
surgeries?: number;
|
|
laboratory?: number;
|
|
imaging?: number;
|
|
pharmacy?: number;
|
|
dental?: number;
|
|
vision?: number;
|
|
mentalHealth?: number;
|
|
preventiveCare?: number;
|
|
}
|
|
|
|
export interface DeductibleInfo {
|
|
individual?: number;
|
|
family?: number;
|
|
inNetwork?: number;
|
|
outOfNetwork?: number;
|
|
}
|
|
|
|
export interface CopayInfo {
|
|
primaryCare?: number;
|
|
specialist?: number;
|
|
urgentCare?: number;
|
|
emergency?: number;
|
|
laboratory?: number;
|
|
imaging?: number;
|
|
genericDrugs?: number;
|
|
brandDrugs?: number;
|
|
specialtyDrugs?: number;
|
|
}
|
|
|
|
export interface OutOfPocketMax {
|
|
individual?: number;
|
|
family?: number;
|
|
inNetwork?: number;
|
|
outOfNetwork?: number;
|
|
}
|
|
|
|
@Entity({ name: 'insurance_plans', schema: 'clinica' })
|
|
export class InsurancePlan {
|
|
@PrimaryGeneratedColumn('uuid')
|
|
id: string;
|
|
|
|
@Index()
|
|
@Column({ name: 'tenant_id', type: 'uuid' })
|
|
tenantId: string;
|
|
|
|
@Index()
|
|
@Column({ name: 'insurance_company_id', type: 'uuid' })
|
|
insuranceCompanyId: string;
|
|
|
|
@ManyToOne(() => InsuranceCompany, (company) => company.plans)
|
|
@JoinColumn({ name: 'insurance_company_id' })
|
|
insuranceCompany: InsuranceCompany;
|
|
|
|
@Index()
|
|
@Column({ type: 'varchar', length: 50 })
|
|
code: string;
|
|
|
|
@Column({ type: 'varchar', length: 200 })
|
|
name: string;
|
|
|
|
@Column({ type: 'text', nullable: true })
|
|
description?: string;
|
|
|
|
@Column({ name: 'coverage_type', type: 'enum', enum: ['individual', 'family', 'group', 'medicare', 'medicaid', 'other'], default: 'individual' })
|
|
coverageType: CoverageType;
|
|
|
|
@Column({ name: 'coverage_percentage', type: 'jsonb', nullable: true })
|
|
coveragePercentage?: CoverageDetails;
|
|
|
|
@Column({ type: 'jsonb', nullable: true })
|
|
deductible?: DeductibleInfo;
|
|
|
|
@Column({ type: 'jsonb', nullable: true })
|
|
copay?: CopayInfo;
|
|
|
|
@Column({ name: 'out_of_pocket_max', type: 'jsonb', nullable: true })
|
|
outOfPocketMax?: OutOfPocketMax;
|
|
|
|
@Column({ name: 'coinsurance_percentage', type: 'decimal', precision: 5, scale: 2, nullable: true })
|
|
coinsurancePercentage?: number;
|
|
|
|
@Column({ name: 'annual_benefit_max', type: 'decimal', precision: 12, scale: 2, nullable: true })
|
|
annualBenefitMax?: number;
|
|
|
|
@Column({ name: 'lifetime_benefit_max', type: 'decimal', precision: 15, scale: 2, nullable: true })
|
|
lifetimeBenefitMax?: number;
|
|
|
|
@Column({ name: 'waiting_period_days', type: 'int', default: 0 })
|
|
waitingPeriodDays: number;
|
|
|
|
@Column({ name: 'preauthorization_required', type: 'boolean', default: false })
|
|
preauthorizationRequired: boolean;
|
|
|
|
@Column({ name: 'referral_required', type: 'boolean', default: false })
|
|
referralRequired: boolean;
|
|
|
|
@Column({ name: 'network_restrictions', type: 'text', nullable: true })
|
|
networkRestrictions?: string;
|
|
|
|
@Column({ name: 'exclusions', type: 'text', nullable: true })
|
|
exclusions?: string;
|
|
|
|
@Column({ name: 'effective_date', type: 'date', nullable: true })
|
|
effectiveDate?: Date;
|
|
|
|
@Column({ name: 'termination_date', type: 'date', nullable: true })
|
|
terminationDate?: Date;
|
|
|
|
@Column({ type: 'enum', enum: ['active', 'inactive', 'discontinued'], default: 'active' })
|
|
status: InsurancePlanStatus;
|
|
|
|
@Column({ type: 'text', nullable: true })
|
|
notes?: string;
|
|
|
|
@OneToMany(() => PatientInsurance, (patientInsurance) => patientInsurance.insurancePlan)
|
|
patientPolicies?: PatientInsurance[];
|
|
|
|
@CreateDateColumn({ name: 'created_at', type: 'timestamptz' })
|
|
createdAt: Date;
|
|
|
|
@UpdateDateColumn({ name: 'updated_at', type: 'timestamptz' })
|
|
updatedAt: Date;
|
|
|
|
@DeleteDateColumn({ name: 'deleted_at', type: 'timestamptz', nullable: true })
|
|
deletedAt?: Date;
|
|
}
|