233 lines
6.8 KiB
Plaintext
233 lines
6.8 KiB
Plaintext
// server/api/queue/patients.ts
|
|
// Contoh implementasi API endpoints untuk antrian pasien
|
|
// NOTE: Ini adalah contoh - sesuaikan dengan database dan framework yang digunakan
|
|
|
|
import type { H3Event } from 'h3'
|
|
|
|
// Mock database (ganti dengan database real)
|
|
const mockDB: any[] = []
|
|
|
|
interface Patient {
|
|
no: number
|
|
jamPanggil: string
|
|
barcode: string
|
|
noAntrian: string
|
|
shift: string
|
|
klinik: string
|
|
fastTrack: string
|
|
pembayaran: string
|
|
status: string
|
|
processStage: string
|
|
createdAt: string
|
|
registrationType?: string
|
|
visitType?: string
|
|
visitDate?: string
|
|
}
|
|
|
|
// GET /api/queue/patients - Get all patients
|
|
export default defineEventHandler(async (event: H3Event) => {
|
|
try {
|
|
// TODO: Replace with actual database query
|
|
// const patients = await db.query('SELECT * FROM patients ORDER BY created_at DESC')
|
|
|
|
// Mock response
|
|
const patients = mockDB
|
|
|
|
return {
|
|
success: true,
|
|
data: patients,
|
|
message: 'Patients fetched successfully',
|
|
}
|
|
} catch (error: any) {
|
|
throw createError({
|
|
statusCode: 500,
|
|
message: error.message || 'Failed to fetch patients',
|
|
})
|
|
}
|
|
})
|
|
|
|
// GET /api/queue/patients/:id - Get single patient
|
|
export default defineEventHandler(async (event: H3Event) => {
|
|
const idOrBarcode = getRouterParam(event, 'id')
|
|
|
|
try {
|
|
// TODO: Replace with actual database query
|
|
// const patient = await db.query('SELECT * FROM patients WHERE barcode = ? OR id = ?', [idOrBarcode, idOrBarcode])
|
|
|
|
const patient = mockDB.find(
|
|
(p: Patient) => p.barcode === idOrBarcode || p.no.toString() === idOrBarcode
|
|
)
|
|
|
|
if (!patient) {
|
|
throw createError({
|
|
statusCode: 404,
|
|
message: 'Patient not found',
|
|
})
|
|
}
|
|
|
|
return {
|
|
success: true,
|
|
data: patient,
|
|
}
|
|
} catch (error: any) {
|
|
if (error.statusCode) throw error
|
|
throw createError({
|
|
statusCode: 500,
|
|
message: error.message || 'Failed to fetch patient',
|
|
})
|
|
}
|
|
})
|
|
|
|
// POST /api/queue/patients - Create new patient
|
|
export default defineEventHandler(async (event: H3Event) => {
|
|
const body = await readBody(event)
|
|
|
|
try {
|
|
// Validate required fields
|
|
if (!body.clinic || !body.paymentType) {
|
|
throw createError({
|
|
statusCode: 400,
|
|
message: 'Missing required fields: clinic, paymentType',
|
|
})
|
|
}
|
|
|
|
// Helper function untuk generate barcode dengan format: YYMMDD + 5 digit sequential
|
|
// Format: YY (tahun 2 digit terakhir) + MM (bulan 2 digit) + DD (tanggal 2 digit) + XXXXX (5 digit sequential)
|
|
// Contoh: 26011400001, 26011400002, dst
|
|
// Counter akan reset setiap ganti tanggal (mulai dari 00001 lagi)
|
|
const generateBarcode = () => {
|
|
const now = new Date();
|
|
const year = String(now.getFullYear()).slice(-2); // 2 digit tahun terakhir
|
|
const month = String(now.getMonth() + 1).padStart(2, '0'); // 2 digit bulan
|
|
const day = String(now.getDate()).padStart(2, '0'); // 2 digit tanggal
|
|
const datePrefix = `${year}${month}${day}`; // YYMMDD
|
|
|
|
// Gunakan counter berdasarkan existing patients untuk sequential
|
|
// NOTE: Di production, gunakan database counter atau shared counter service
|
|
const existingCount = mockDB.filter(p => p.barcode && p.barcode.startsWith(datePrefix)).length;
|
|
const counter = existingCount + 1;
|
|
const counterCode = String(counter).padStart(5, '0'); // 5 digit sequential
|
|
return `${datePrefix}${counterCode}`;
|
|
};
|
|
|
|
// Generate patient data
|
|
const barcode = generateBarcode();
|
|
const newPatient: Patient = {
|
|
no: mockDB.length + 1,
|
|
jamPanggil: new Date().toLocaleTimeString('id-ID', { hour: '2-digit', minute: '2-digit' }),
|
|
barcode: barcode,
|
|
noAntrian: `UM${String(mockDB.length + 1).padStart(4, '0')} | Onsite - ${barcode}`,
|
|
shift: body.shift || 'Shift 1',
|
|
klinik: body.clinic,
|
|
fastTrack: 'TIDAK',
|
|
pembayaran: body.paymentType,
|
|
status: body.visitType === 'SEKARANG' ? 'waiting' : 'pending',
|
|
processStage: 'loket',
|
|
createdAt: new Date().toISOString(),
|
|
registrationType: 'onsite',
|
|
visitType: body.visitType || 'SEKARANG',
|
|
visitDate: body.visitDate || new Date().toISOString().substring(0, 10),
|
|
}
|
|
|
|
// TODO: Insert to database
|
|
// await db.query('INSERT INTO patients SET ?', newPatient)
|
|
mockDB.push(newPatient)
|
|
|
|
return {
|
|
success: true,
|
|
data: newPatient,
|
|
message: 'Patient created successfully',
|
|
}
|
|
} catch (error: any) {
|
|
if (error.statusCode) throw error
|
|
throw createError({
|
|
statusCode: 500,
|
|
message: error.message || 'Failed to create patient',
|
|
})
|
|
}
|
|
})
|
|
|
|
// PATCH /api/queue/patients/:id - Update patient
|
|
export default defineEventHandler(async (event: H3Event) => {
|
|
const idOrBarcode = getRouterParam(event, 'id')
|
|
const body = await readBody(event)
|
|
|
|
try {
|
|
// TODO: Replace with actual database query
|
|
// const patient = await db.query('SELECT * FROM patients WHERE barcode = ? OR id = ?', [idOrBarcode, idOrBarcode])
|
|
|
|
const patientIndex = mockDB.findIndex(
|
|
(p: Patient) => p.barcode === idOrBarcode || p.no.toString() === idOrBarcode
|
|
)
|
|
|
|
if (patientIndex === -1) {
|
|
throw createError({
|
|
statusCode: 404,
|
|
message: 'Patient not found',
|
|
})
|
|
}
|
|
|
|
// Update patient
|
|
const updatedPatient = {
|
|
...mockDB[patientIndex],
|
|
...body,
|
|
updatedAt: new Date().toISOString(),
|
|
}
|
|
|
|
// TODO: Update in database
|
|
// await db.query('UPDATE patients SET ? WHERE barcode = ?', [body, idOrBarcode])
|
|
mockDB[patientIndex] = updatedPatient
|
|
|
|
return {
|
|
success: true,
|
|
data: updatedPatient,
|
|
message: 'Patient updated successfully',
|
|
}
|
|
} catch (error: any) {
|
|
if (error.statusCode) throw error
|
|
throw createError({
|
|
statusCode: 500,
|
|
message: error.message || 'Failed to update patient',
|
|
})
|
|
}
|
|
})
|
|
|
|
// POST /api/queue/patients/batch - Batch sync
|
|
export default defineEventHandler(async (event: H3Event) => {
|
|
const body = await readBody(event)
|
|
const { patients } = body
|
|
|
|
try {
|
|
if (!Array.isArray(patients)) {
|
|
throw createError({
|
|
statusCode: 400,
|
|
message: 'patients must be an array',
|
|
})
|
|
}
|
|
|
|
// TODO: Batch insert/update to database
|
|
// await db.query('INSERT INTO patients VALUES ? ON DUPLICATE KEY UPDATE ...', [patients])
|
|
|
|
patients.forEach((patient: Patient) => {
|
|
const index = mockDB.findIndex((p: Patient) => p.barcode === patient.barcode)
|
|
if (index === -1) {
|
|
mockDB.push(patient)
|
|
} else {
|
|
mockDB[index] = patient
|
|
}
|
|
})
|
|
|
|
return {
|
|
success: true,
|
|
message: `Synced ${patients.length} patients`,
|
|
}
|
|
} catch (error: any) {
|
|
if (error.statusCode) throw error
|
|
throw createError({
|
|
statusCode: 500,
|
|
message: error.message || 'Failed to batch sync',
|
|
})
|
|
}
|
|
})
|
|
|