Skip to content

Commit c82a0de

Browse files
authored
Merge pull request #107 from genzz-dev/feature/quicklabs-backend
Feature/quicklabs backend
2 parents e6d9f8d + 13de8be commit c82a0de

24 files changed

Lines changed: 1993 additions & 101 deletions

server/Controllers/QuickLab/labAdminController.js

Lines changed: 419 additions & 0 deletions
Large diffs are not rendered by default.

server/Controllers/QuickLab/labAppointmentController.js

Lines changed: 415 additions & 0 deletions
Large diffs are not rendered by default.
Lines changed: 79 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,79 @@
1+
// controllers/labController.js (for patient/doctor to search labs)
2+
import Lab from '../../models/Lab/Lab.js';
3+
4+
// Search labs
5+
export const searchLabs = async (req, res) => {
6+
try {
7+
const { name, city, testName } = req.query;
8+
9+
const query = { isActive: true };
10+
11+
if (name) {
12+
query.name = { $regex: name, $options: 'i' };
13+
}
14+
15+
if (city) {
16+
query['address.city'] = { $regex: city, $options: 'i' };
17+
}
18+
19+
if (testName) {
20+
query['tests.testName'] = { $regex: testName, $options: 'i' };
21+
}
22+
23+
const labs = await Lab.find(query)
24+
.select(
25+
'name description address contact logo ratings tests homeCollectionAvailable homeCollectionFee'
26+
)
27+
.lean();
28+
29+
res.json({
30+
count: labs.length,
31+
labs,
32+
});
33+
} catch (error) {
34+
console.error('Error searching labs:', error);
35+
res.status(500).json({ message: 'Failed to search labs' });
36+
}
37+
};
38+
39+
// Get lab details
40+
export const getLabDetails = async (req, res) => {
41+
try {
42+
const { labId } = req.params;
43+
44+
const lab = await Lab.findById(labId).select('-staff -labAdminId').lean();
45+
46+
if (!lab) {
47+
return res.status(404).json({ message: 'Lab not found' });
48+
}
49+
50+
res.json({ lab });
51+
} catch (error) {
52+
console.error('Error fetching lab details:', error);
53+
res.status(500).json({ message: 'Failed to fetch lab details' });
54+
}
55+
};
56+
57+
// Get lab tests
58+
export const getLabTests = async (req, res) => {
59+
try {
60+
const { labId } = req.params;
61+
62+
const lab = await Lab.findById(labId).select('tests name').lean();
63+
64+
if (!lab) {
65+
return res.status(404).json({ message: 'Lab not found' });
66+
}
67+
68+
const activeTests = lab.tests.filter((test) => test.isActive);
69+
70+
res.json({
71+
labName: lab.name,
72+
count: activeTests.length,
73+
tests: activeTests,
74+
});
75+
} catch (error) {
76+
console.error('Error fetching lab tests:', error);
77+
res.status(500).json({ message: 'Failed to fetch tests' });
78+
}
79+
};
Lines changed: 174 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,174 @@
1+
// controllers/labReportController.js
2+
import mongoose from 'mongoose';
3+
import LabReport from '../../models/Lab/LabReport.js';
4+
import LabAppointment from '../../models/Lab/LabAppointment.js';
5+
import { uploadToCloudinary } from '../../services/uploadService.js';
6+
7+
// Upload lab report (by lab admin/staff)
8+
export const uploadLabReport = async (req, res) => {
9+
try {
10+
const { appointmentId } = req.params;
11+
const { testResults } = req.body;
12+
13+
if (!req.file) {
14+
return res.status(400).json({ message: 'Report file is required' });
15+
}
16+
17+
const appointment = await LabAppointment.findById(appointmentId);
18+
if (!appointment) {
19+
return res.status(404).json({ message: 'Appointment not found' });
20+
}
21+
22+
// Upload report file
23+
const uploadResult = await uploadToCloudinary(req.file.path);
24+
25+
const report = new LabReport({
26+
appointmentId,
27+
patientId: appointment.patientId,
28+
labId: appointment.labId,
29+
doctorId: appointment.suggestedByDoctorId || undefined,
30+
testResults: testResults ? JSON.parse(testResults) : [],
31+
reportFile: {
32+
url: uploadResult.url,
33+
fileName: req.file.originalname,
34+
},
35+
isSharedWithDoctor: !!appointment.suggestedByDoctorId,
36+
});
37+
38+
await report.save();
39+
40+
// Update appointment
41+
appointment.reportId = report._id;
42+
appointment.status = 'completed';
43+
await appointment.save();
44+
45+
res.status(201).json({
46+
message: 'Lab report uploaded successfully',
47+
report: report.toObject({ getters: true }),
48+
});
49+
} catch (error) {
50+
console.error('Error uploading lab report:', error);
51+
res.status(500).json({ message: 'Failed to upload report' });
52+
}
53+
};
54+
55+
// Get patient's lab reports
56+
export const getPatientLabReports = async (req, res) => {
57+
try {
58+
const { profileId } = req.user;
59+
60+
const reports = await LabReport.find({ patientId: profileId })
61+
.populate('labId', 'name address')
62+
.populate('doctorId', 'firstName lastName specialization')
63+
.populate('appointmentId', 'tests appointmentDate')
64+
.sort({ reportDate: -1 })
65+
.lean();
66+
67+
res.json({
68+
count: reports.length,
69+
reports,
70+
});
71+
} catch (error) {
72+
console.error('Error fetching patient reports:', error);
73+
res.status(500).json({ message: 'Failed to fetch reports' });
74+
}
75+
};
76+
77+
// Get doctor's patient lab reports (reports shared with doctor)
78+
export const getDoctorPatientReports = async (req, res) => {
79+
try {
80+
const { profileId } = req.user;
81+
82+
const reports = await LabReport.find({
83+
doctorId: profileId,
84+
isSharedWithDoctor: true,
85+
})
86+
.populate('patientId', 'firstName lastName dateOfBirth gender')
87+
.populate('labId', 'name')
88+
.populate('appointmentId', 'tests appointmentDate')
89+
.sort({ reportDate: -1 })
90+
.lean();
91+
92+
res.json({
93+
count: reports.length,
94+
reports,
95+
});
96+
} catch (error) {
97+
console.error('Error fetching doctor reports:', error);
98+
res.status(500).json({ message: 'Failed to fetch reports' });
99+
}
100+
};
101+
102+
// Add doctor remarks to report
103+
export const addDoctorRemarks = async (req, res) => {
104+
try {
105+
const { reportId } = req.params;
106+
const { profileId } = req.user;
107+
const { remarks } = req.body;
108+
109+
if (!remarks) {
110+
return res.status(400).json({ message: 'Remarks are required' });
111+
}
112+
113+
const report = await LabReport.findById(reportId);
114+
if (!report) {
115+
return res.status(404).json({ message: 'Report not found' });
116+
}
117+
118+
if (report.doctorId && report.doctorId.toString() !== profileId.toString()) {
119+
return res.status(403).json({ message: 'Unauthorized to add remarks to this report' });
120+
}
121+
122+
report.doctorRemarks = {
123+
remarks,
124+
addedAt: new Date(),
125+
addedBy: profileId,
126+
};
127+
128+
await report.save();
129+
130+
res.json({
131+
message: 'Remarks added successfully',
132+
report,
133+
});
134+
} catch (error) {
135+
console.error('Error adding remarks:', error);
136+
res.status(500).json({ message: 'Failed to add remarks' });
137+
}
138+
};
139+
140+
// Get specific report details
141+
export const getReportDetails = async (req, res) => {
142+
try {
143+
const { reportId } = req.params;
144+
const { profileId, role } = req.user;
145+
146+
const report = await LabReport.findById(reportId)
147+
.populate('patientId', 'firstName lastName dateOfBirth gender')
148+
.populate('labId', 'name address contact')
149+
.populate('doctorId', 'firstName lastName specialization')
150+
.populate('appointmentId')
151+
.lean();
152+
153+
if (!report) {
154+
return res.status(404).json({ message: 'Report not found' });
155+
}
156+
157+
// Authorization check
158+
if (role === 'patient' && report.patientId._id.toString() !== profileId.toString()) {
159+
return res.status(403).json({ message: 'Unauthorized' });
160+
}
161+
162+
if (
163+
role === 'doctor' &&
164+
(!report.doctorId || report.doctorId._id.toString() !== profileId.toString())
165+
) {
166+
return res.status(403).json({ message: 'Unauthorized' });
167+
}
168+
169+
res.json({ report });
170+
} catch (error) {
171+
console.error('Error fetching report details:', error);
172+
res.status(500).json({ message: 'Failed to fetch report' });
173+
}
174+
};

0 commit comments

Comments
 (0)