feat: validation delete tindakan
This commit is contained in:
parent
4d4565299d
commit
cbcf4ad897
|
|
@ -112,6 +112,7 @@ export class AuditService {
|
|||
).filter((record): record is AuditRecordPayload => record !== null);
|
||||
|
||||
if (records.length > 0) {
|
||||
console.log(records);
|
||||
await this.prisma.$transaction(
|
||||
records.map((record) =>
|
||||
this.prisma.audit.upsert({
|
||||
|
|
@ -121,7 +122,7 @@ export class AuditService {
|
|||
event: record.event,
|
||||
payload: record.payload,
|
||||
timestamp: record.timestamp,
|
||||
user_id: record.user_id,
|
||||
user_id: BigInt(record.user_id),
|
||||
last_sync: record.last_sync,
|
||||
result: record.result,
|
||||
},
|
||||
|
|
@ -133,7 +134,6 @@ export class AuditService {
|
|||
|
||||
if (nextBookmark === '' || nextBookmark === bookmark) {
|
||||
const completeData = { status: 'COMPLETED' };
|
||||
this.logger.log('Mengirim selesai via WebSocket:', completeData);
|
||||
this.auditGateway.sendComplete(completeData);
|
||||
break;
|
||||
}
|
||||
|
|
@ -213,6 +213,7 @@ export class AuditService {
|
|||
const timestamp = this.parseTimestamp(value.timestamp) ?? now;
|
||||
const userId = value.user_id;
|
||||
const blockchainHash: string | undefined = value.payload;
|
||||
let data: any = null;
|
||||
|
||||
if (!blockchainHash) {
|
||||
return null;
|
||||
|
|
@ -224,6 +225,7 @@ export class AuditService {
|
|||
const obatId = this.extractNumericId(logId);
|
||||
if (obatId !== null) {
|
||||
const obat = await this.obatService.getObatById(obatId);
|
||||
data = obat;
|
||||
if (obat) {
|
||||
dbHash = this.obatService.createHashingPayload({
|
||||
obat: obat.obat,
|
||||
|
|
@ -237,6 +239,7 @@ export class AuditService {
|
|||
if (rekamMedisId) {
|
||||
const rekamMedis =
|
||||
await this.rekamMedisService.getRekamMedisById(rekamMedisId);
|
||||
data = rekamMedis;
|
||||
if (rekamMedis) {
|
||||
dbHash = this.rekamMedisService.createHashingPayload({
|
||||
dokter_id: 123,
|
||||
|
|
@ -252,6 +255,7 @@ export class AuditService {
|
|||
if (tindakanId !== null) {
|
||||
const tindakanDokter =
|
||||
await this.tindakanDokterService.getTindakanDokterById(tindakanId);
|
||||
data = tindakanDokter;
|
||||
if (tindakanDokter) {
|
||||
dbHash = this.tindakanDokterService.createHashingPayload({
|
||||
id_visit: tindakanDokter.id_visit,
|
||||
|
|
@ -270,10 +274,13 @@ export class AuditService {
|
|||
|
||||
let isNotTampered = false;
|
||||
const eventType = logEntry.value.event?.split('_').at(-1);
|
||||
const isDeleteEvent = eventType === 'deleted';
|
||||
const hasRow = Boolean(data);
|
||||
|
||||
if (eventType === 'deleted') {
|
||||
isNotTampered = true;
|
||||
console.log('Detected deleted event, marking as not tempered');
|
||||
if (!hasRow) {
|
||||
isNotTampered = isDeleteEvent;
|
||||
} else if (isDeleteEvent || data.deleted_status === 'DELETED') {
|
||||
isNotTampered = isDeleteEvent && data.deleted_status === 'DELETED';
|
||||
} else {
|
||||
const hashesMatch =
|
||||
dbHash && (await this.compareData(blockchainHash, dbHash));
|
||||
|
|
@ -287,7 +294,7 @@ export class AuditService {
|
|||
progress_count: index ?? 0,
|
||||
};
|
||||
|
||||
this.logger.log('Mengirim progres via WebSocket:', progressData);
|
||||
// this.logger.log('Mengirim progres via WebSocket:', progressData);
|
||||
this.auditGateway.sendProgress(progressData);
|
||||
|
||||
return {
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
import {
|
||||
Body,
|
||||
Controller,
|
||||
Delete,
|
||||
Get,
|
||||
Param,
|
||||
Post,
|
||||
|
|
@ -69,4 +70,13 @@ export class ObatController {
|
|||
async getObatLogs(@Param('id') id: string) {
|
||||
return await this.obatService.getLogObatById(id);
|
||||
}
|
||||
|
||||
@Delete(':id')
|
||||
@UseGuards(AuthGuard)
|
||||
async deleteObatById(
|
||||
@Param('id') id: number,
|
||||
@CurrentUser() user: ActiveUserPayload,
|
||||
) {
|
||||
return await this.obatService.deleteObat(id, user);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -56,6 +56,11 @@ export class ObatService {
|
|||
take: take,
|
||||
where: {
|
||||
obat: obat ? { contains: obat } : undefined,
|
||||
OR: [
|
||||
{ deleted_status: null },
|
||||
{ deleted_status: 'DELETE_VALIDATION' },
|
||||
{ deleted_status: { not: 'DELETED' } },
|
||||
],
|
||||
},
|
||||
orderBy: orderBy
|
||||
? { [Object.keys(orderBy)[0]]: order || 'asc' }
|
||||
|
|
@ -65,6 +70,11 @@ export class ObatService {
|
|||
const count = await this.prisma.pemberian_obat.count({
|
||||
where: {
|
||||
obat: obat ? { contains: obat } : undefined,
|
||||
OR: [
|
||||
{ deleted_status: null },
|
||||
{ deleted_status: 'DELETE_VALIDATION' },
|
||||
{ deleted_status: { not: 'DELETED' } },
|
||||
],
|
||||
},
|
||||
});
|
||||
|
||||
|
|
@ -273,6 +283,89 @@ export class ObatService {
|
|||
}
|
||||
}
|
||||
|
||||
async deleteObat(id: number, user: ActiveUserPayload) {
|
||||
const existingObat = await this.getObatById(id);
|
||||
if (!existingObat) {
|
||||
throw new BadRequestException(`Obat with id ${id} not found`);
|
||||
}
|
||||
|
||||
try {
|
||||
const response = await this.prisma.$transaction(async (tx) => {
|
||||
const createdValidationQueue =
|
||||
await this.prisma.validation_queue.create({
|
||||
data: {
|
||||
table_name: 'pemberian_obat',
|
||||
action: 'DELETE',
|
||||
dataPayload: {
|
||||
...existingObat,
|
||||
},
|
||||
record_id: id.toString(),
|
||||
user_id_request: Number(user.sub),
|
||||
status: 'PENDING',
|
||||
},
|
||||
});
|
||||
|
||||
const updatedObat = await tx.pemberian_obat.update({
|
||||
where: { id: id },
|
||||
data: {
|
||||
deleted_status: 'DELETE_VALIDATION',
|
||||
},
|
||||
});
|
||||
|
||||
return createdValidationQueue;
|
||||
});
|
||||
return response;
|
||||
} catch (error) {
|
||||
console.error('Error deleting Obat:', error);
|
||||
throw error;
|
||||
}
|
||||
}
|
||||
|
||||
async deleteObatFromDBAndBlockchain(id: number, userId: number) {
|
||||
const obatId = Number(id);
|
||||
|
||||
if (isNaN(obatId)) {
|
||||
throw new BadRequestException('ID obat tidak valid');
|
||||
}
|
||||
|
||||
const existingObat = await this.getObatById(obatId);
|
||||
if (!existingObat) {
|
||||
throw new BadRequestException(`Obat dengan ID ${obatId} tidak ditemukan`);
|
||||
}
|
||||
|
||||
try {
|
||||
const deleteObat = await this.prisma.$transaction(async (tx) => {
|
||||
const deletedObat = await tx.pemberian_obat.update({
|
||||
where: { id: obatId },
|
||||
data: {
|
||||
deleted_status: 'DELETED',
|
||||
},
|
||||
});
|
||||
const logPayload = JSON.stringify({
|
||||
obat: existingObat.obat,
|
||||
jumlah_obat: existingObat.jumlah_obat,
|
||||
aturan_pakai: existingObat.aturan_pakai,
|
||||
});
|
||||
const payloadHash = sha256(logPayload);
|
||||
const data = {
|
||||
id: `OBAT_${deletedObat.id}`,
|
||||
event: 'obat_deleted',
|
||||
user_id: userId.toString(),
|
||||
payload: payloadHash,
|
||||
};
|
||||
const logResult = await this.logService.storeLog(data);
|
||||
return {
|
||||
...deletedObat,
|
||||
...logResult,
|
||||
};
|
||||
});
|
||||
return deleteObat;
|
||||
} catch (error) {
|
||||
console.error('Error deleting Obat:', error);
|
||||
throw error;
|
||||
}
|
||||
}
|
||||
|
||||
async countObat() {
|
||||
return this.prisma.pemberian_obat.count();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -195,6 +195,11 @@ export class RekammedisService {
|
|||
: undefined,
|
||||
jenis_kelamin: jkCharacter ? { equals: jkCharacter } : undefined,
|
||||
kode_diagnosa: kode_diagnosa ? { contains: kode_diagnosa } : undefined,
|
||||
OR: [
|
||||
{ deleted_status: null },
|
||||
{ deleted_status: 'DELETE_VALIDATION' },
|
||||
{ deleted_status: { not: 'DELETED' } },
|
||||
],
|
||||
...golDarahFilter,
|
||||
...tindakLanjutFilter,
|
||||
};
|
||||
|
|
@ -469,15 +474,28 @@ export class RekammedisService {
|
|||
throw new Error(`Rekam Medis with id_visit ${id_visit} not found`);
|
||||
}
|
||||
try {
|
||||
const response = await this.prisma.validation_queue.create({
|
||||
data: {
|
||||
table_name: 'rekam_medis',
|
||||
action: 'DELETE',
|
||||
record_id: id_visit,
|
||||
dataPayload: data,
|
||||
user_id_request: user.sub,
|
||||
status: 'PENDING',
|
||||
},
|
||||
const response = await this.prisma.$transaction(async (tx) => {
|
||||
const createdQueue = await tx.validation_queue.create({
|
||||
data: {
|
||||
table_name: 'rekam_medis',
|
||||
action: 'DELETE',
|
||||
record_id: id_visit,
|
||||
dataPayload: data,
|
||||
user_id_request: user.sub,
|
||||
status: 'PENDING',
|
||||
},
|
||||
});
|
||||
|
||||
const updatedRekamMedis = await tx.rekam_medis.update({
|
||||
where: { id_visit },
|
||||
data: {
|
||||
deleted_status: 'DELETE_VALIDATION',
|
||||
},
|
||||
});
|
||||
return {
|
||||
...createdQueue,
|
||||
rekam_medis: updatedRekamMedis,
|
||||
};
|
||||
});
|
||||
return response;
|
||||
} catch (error) {
|
||||
|
|
@ -486,10 +504,39 @@ export class RekammedisService {
|
|||
}
|
||||
}
|
||||
|
||||
async deleteRekamMedisFromDB(id_visit: string) {
|
||||
async deleteRekamMedisFromDBAndBlockchain(id_visit: string, userId: number) {
|
||||
const existing = await this.getRekamMedisById(id_visit);
|
||||
if (!existing) {
|
||||
throw new Error(`Rekam Medis with id_visit ${id_visit} not found`);
|
||||
}
|
||||
|
||||
try {
|
||||
const deletedRekamMedis = await this.prisma.rekam_medis.delete({
|
||||
where: { id_visit },
|
||||
const deletedRekamMedis = await this.prisma.$transaction(async (tx) => {
|
||||
const deleted = await tx.rekam_medis.update({
|
||||
data: {
|
||||
deleted_status: 'DELETED',
|
||||
},
|
||||
where: { id_visit },
|
||||
});
|
||||
|
||||
const logPayload = {
|
||||
dokter_id: 123,
|
||||
visit_id: id_visit,
|
||||
anamnese: deleted.anamnese,
|
||||
jenis_kasus: deleted.jenis_kasus,
|
||||
tindak_lanjut: deleted.tindak_lanjut,
|
||||
};
|
||||
const logPayloadString = JSON.stringify(logPayload);
|
||||
const payloadHash = sha256(logPayloadString);
|
||||
const logDto = {
|
||||
id: `REKAM_${id_visit}`,
|
||||
event: 'rekam_medis_deleted',
|
||||
user_id: userId.toString(),
|
||||
payload: payloadHash,
|
||||
};
|
||||
|
||||
await this.log.storeLog(logDto);
|
||||
return deleted;
|
||||
});
|
||||
return deletedRekamMedis;
|
||||
} catch (error) {
|
||||
|
|
|
|||
|
|
@ -79,6 +79,11 @@ export class TindakanDokterService {
|
|||
kategori_tindakanArray.length > 0
|
||||
? { in: kategori_tindakanArray }
|
||||
: undefined,
|
||||
OR: [
|
||||
{ deleted_status: null },
|
||||
{ deleted_status: 'DELETE_VALIDATION' },
|
||||
{ deleted_status: { not: 'DELETED' } },
|
||||
],
|
||||
},
|
||||
orderBy: orderBy
|
||||
? { [Object.keys(orderBy)[0]]: order || 'asc' }
|
||||
|
|
@ -331,16 +336,36 @@ export class TindakanDokterService {
|
|||
);
|
||||
}
|
||||
|
||||
return this.prisma.validation_queue.create({
|
||||
data: {
|
||||
table_name: 'pemberian_tindakan',
|
||||
action: 'DELETE',
|
||||
dataPayload: existingTindakan,
|
||||
record_id: tindakanId.toString(),
|
||||
user_id_request: user.sub,
|
||||
status: 'PENDING',
|
||||
},
|
||||
});
|
||||
try {
|
||||
const validationQueue = await this.prisma.$transaction(async (tx) => {
|
||||
const queue = await tx.validation_queue.create({
|
||||
data: {
|
||||
table_name: 'pemberian_tindakan',
|
||||
action: 'DELETE',
|
||||
dataPayload: existingTindakan,
|
||||
record_id: tindakanId.toString(),
|
||||
user_id_request: user.sub,
|
||||
status: 'PENDING',
|
||||
},
|
||||
});
|
||||
|
||||
const updatedTindakan = await tx.pemberian_tindakan.update({
|
||||
where: { id: tindakanId },
|
||||
data: {
|
||||
deleted_status: 'DELETE_VALIDATION',
|
||||
},
|
||||
});
|
||||
return {
|
||||
...queue,
|
||||
tindakan: updatedTindakan,
|
||||
};
|
||||
});
|
||||
|
||||
return validationQueue;
|
||||
} catch (error) {
|
||||
console.error('Error deleting Tindakan Dokter:', error);
|
||||
throw error;
|
||||
}
|
||||
}
|
||||
|
||||
async deleteTindakanDokterFromDBAndBlockchain(id: number, userId: number) {
|
||||
|
|
@ -359,8 +384,9 @@ export class TindakanDokterService {
|
|||
|
||||
try {
|
||||
const deletedTindakan = await this.prisma.$transaction(async (tx) => {
|
||||
const deleted = await tx.pemberian_tindakan.delete({
|
||||
const deleted = await tx.pemberian_tindakan.update({
|
||||
where: { id: tindakanId },
|
||||
data: { deleted_status: 'DELETED' },
|
||||
});
|
||||
const logPayload = JSON.stringify(deleted);
|
||||
const payloadHash = sha256(logPayload);
|
||||
|
|
|
|||
|
|
@ -46,7 +46,10 @@ export class ValidationService {
|
|||
);
|
||||
},
|
||||
approveDelete: async (queue: any) => {
|
||||
return this.rekamMedisService.deleteRekamMedisFromDB(queue.record_id);
|
||||
return this.rekamMedisService.deleteRekamMedisFromDBAndBlockchain(
|
||||
queue.record_id,
|
||||
Number(queue.user_id_request),
|
||||
);
|
||||
},
|
||||
},
|
||||
pemberian_tindakan: {
|
||||
|
|
@ -97,6 +100,12 @@ export class ValidationService {
|
|||
Number(queue.user_id_request),
|
||||
);
|
||||
},
|
||||
approveDelete: async (queue: any) => {
|
||||
return this.obatService.deleteObatFromDBAndBlockchain(
|
||||
Number(queue.record_id),
|
||||
queue.user_id_request,
|
||||
);
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
|
|
@ -196,7 +205,10 @@ export class ValidationService {
|
|||
const updated = await this.prisma.validation_queue.update({
|
||||
where: { id: validationQueue.id },
|
||||
data: {
|
||||
record_id: approvalResult.id.toString(),
|
||||
record_id:
|
||||
validationQueue.table_name === 'rekam_medis'
|
||||
? approvalResult.id_visit
|
||||
: approvalResult.id.toString(),
|
||||
status: 'APPROVED',
|
||||
user_id_process: Number(user.sub),
|
||||
processed_at: new Date(),
|
||||
|
|
|
|||
|
|
@ -155,14 +155,12 @@ const handleUpdate = (item: ObatData) => {
|
|||
};
|
||||
|
||||
const handleDelete = async (item: ObatData) => {
|
||||
if (confirm(`Apakah Anda yakin ingin menghapus obat "${item.obat}"?`)) {
|
||||
try {
|
||||
await api.delete(`/obat/${item.id}`);
|
||||
await fetchData();
|
||||
} catch (error) {
|
||||
console.error("Error deleting obat:", error);
|
||||
alert("Gagal menghapus data obat");
|
||||
}
|
||||
try {
|
||||
await api.delete(`/obat/${item.id}`);
|
||||
await fetchData();
|
||||
} catch (error) {
|
||||
console.error("Error deleting obat:", error);
|
||||
alert("Gagal menghapus data obat");
|
||||
}
|
||||
};
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user