BaseResponse { status: 'failed' | 'error' | 'success' message: string status_code: number data: any } EnumTestStatus Draft Formulir terkirim Formulir ditolak Formulir Diterima=Menunggu pembayaran dan sampel Pembayaran dan sampel diterima=Menunggu diserahkan ke Analis Diserahkan ke Analis Diserahkan ke penyelia=Menunggu Evaluasi LHU oleh penyelia Selesai diuji=menunggu persetujuan korbid Disetujui korbid=Menunggu Verifikasi LHU oleh Ketua PLT Disetujui Ka PLT=Selesai Dibatalkan EnumUserRole Umum Super Admin Super Admin Layanan Pengujian Admin Pemesanan Analis Penyedia Korbid Pengujian Kepala PLT Super Admin Stock Opname Admin Stock Opname Agripa Admin Stock Opname Tisimat Admin Stock Opname Tambang Admin Stock Opname Pengujian User { _id: ID fullname: string address: string institute: string job_title: string phone: string birth_date: date reset_token: string is_data_completed: boolean is_email_verified: boolean roles: [EnumUserRole] NIP: string signature_image_path: string created_at: date updated_at: date } Test { _id: ID id_test: // autogenerated: YYYYMM000${IncreamentTest} sample_name: string sample_quantity: number, sample_type: 'cair' | 'padat', samples: [Sample] test_parameters: [TestParameter] unit_price: number // sum of TestParameter.price total_price: number // Test.unit_price * Test.sample_quantity payment_status: belum diterima | sudah diterima sample_status: belum diterima | sudah diterima current_status: EnumTestStatus histories: [ status: EnumTestStatus remark: string updated_by: User | ID date: date ], korbid: User | ID dekan: User | ID buyer: User | ID } Sample { _id: ID customer_label: string lab_label: string // autogenerated: K-YYYYMM000${IncreamentTest}-${IncreamentThisSample} results: [ test_parameter: TestParameter unit_of_measurement: string result: string ] } TestParameter{ _id: ID test_parameter_name: string instrument: Instrument | ID is_measurable: boolean price: number } Instrument { _id: ID name: string } register() payload: email password response: BaseResponse data: User token: string login() payload: email password response: BaseResponse data: User token: string sendEmailVerification() response: BaseResponse data: null sendEmailResetPassword() payload: email: string response: BaseResponse data: null checkResetToken() payload: reset_token: string response: BaseResponse data: null resetPassword() payload: new_password: string reset_token: string response: BaseResponse data: null editMe() payload: User response: BaseResponse data: null validation: - if payload.User.password, hash User.password - if payload.User.email, flag User.is_email_verified to false getMe() response: User getTests() response: BaseResponse data: test: [Test] getOneTest() response: BaseResponse data: Test createUpdateTest() payload: Test remark: string response: BaseResponse data: null validation: - if payload.Test.current_status, push Test.histories updateTestParameter() payload: TestParameter response: BaseResponse data: null validation: - if payload.TestParameter.price, update unit_test and total_test in Test TODO: - crud data master - crud user managements PaginationResponse { page: number per_page: number total: number total_pages: number data: Array }