erp-clinicas-backend-v2/src/modules/insurance/entities/insurance-plan.entity.ts
Adrian Flores Cortes 1b38818354 [CL-010] feat: Implement insurance module for medical insurance management
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>
2026-01-30 19:59:47 -06:00

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;
}