Spaces:
Sleeping
Sleeping
File size: 4,351 Bytes
c98875e | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 | import { Injectable, NotFoundException } from '@nestjs/common';
import { InjectModel } from '@nestjs/mongoose';
import { Model } from 'mongoose';
import { DiagnosticCode, DiagnosticCodeDocument } from './schemas/diagnostic-code.schema';
import { ProcedureCode, ProcedureCodeDocument } from './schemas/procedure-code.schema';
import { CreateDiagnosticCodeDto } from './dto/create-diagnostic-code.dto';
import { CreateProcedureCodeDto } from './dto/create-procedure-code.dto';
import { SearchCodesDto } from './dto/search-codes.dto';
export interface GlobalSearchResult {
icd10: Array<Record<string, any> & { type: string }>;
cpt: Array<Record<string, any> & { type: string }>;
}
@Injectable()
export class CodesService {
constructor(
@InjectModel(DiagnosticCode.name) private icd10Model: Model<DiagnosticCodeDocument>,
@InjectModel(ProcedureCode.name) private cptModel: Model<ProcedureCodeDocument>,
) {}
// βββ ICD-10 βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
async searchICD10(dto: SearchCodesDto) {
const { q, page = 1, limit = 20, category, billable } = dto;
const filter: any = { isActive: true };
if (q) {
filter.$or = [
{ code: { $regex: q, $options: 'i' } },
{ description: { $regex: q, $options: 'i' } },
];
}
if (category) filter.category = category;
if (billable !== undefined) filter.billable = billable;
const [data, total] = await Promise.all([
this.icd10Model
.find(filter)
.skip((page - 1) * limit)
.limit(limit)
.sort({ code: 1 }),
this.icd10Model.countDocuments(filter),
]);
return { data, total, page, limit, pages: Math.ceil(total / limit) };
}
async getICD10ByCode(code: string) {
const result = await this.icd10Model.findOne({ code: code.toUpperCase() });
if (!result) throw new NotFoundException(`ICD-10 code ${code} not found`);
return result;
}
async createICD10(dto: CreateDiagnosticCodeDto) {
return this.icd10Model.create(dto);
}
async getICD10Categories() {
return this.icd10Model.distinct('category', { isActive: true });
}
// βββ CPT ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
async searchCPT(dto: SearchCodesDto) {
const { q, page = 1, limit = 20, category, billable } = dto;
const filter: any = { isActive: true };
if (q) {
filter.$or = [
{ code: { $regex: q, $options: 'i' } },
{ description: { $regex: q, $options: 'i' } },
];
}
if (category) filter.category = category;
if (billable !== undefined) filter.billable = billable;
const [data, total] = await Promise.all([
this.cptModel
.find(filter)
.skip((page - 1) * limit)
.limit(limit)
.sort({ code: 1 }),
this.cptModel.countDocuments(filter),
]);
return { data, total, page, limit, pages: Math.ceil(total / limit) };
}
async getCPTByCode(code: string) {
const result = await this.cptModel.findOne({ code });
if (!result) throw new NotFoundException(`CPT code ${code} not found`);
return result;
}
async createCPT(dto: CreateProcedureCodeDto) {
return this.cptModel.create(dto);
}
async getCPTCategories() {
return this.cptModel.distinct('category', { isActive: true });
}
// βββ Global search ββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
async globalSearch(q: string, limit = 10): Promise<GlobalSearchResult> {
const filter = {
isActive: true,
$or: [
{ code: { $regex: q, $options: 'i' } },
{ description: { $regex: q, $options: 'i' } },
],
};
const [icd10, cpt] = await Promise.all([
this.icd10Model.find(filter).limit(limit).lean(),
this.cptModel.find(filter).limit(limit).lean(),
]);
return {
icd10: icd10.map((c) => ({ ...c, type: 'ICD-10' })),
cpt: cpt.map((c) => ({ ...c, type: 'CPT' })),
};
}
} |