diff --git a/.gitignore b/.gitignore
index 549e00a..1d0e93b 100644
--- a/.gitignore
+++ b/.gitignore
@@ -31,3 +31,5 @@ build/
### VS Code ###
.vscode/
+
+.env
\ No newline at end of file
diff --git a/Dockerfile b/Dockerfile
index d1a9341..3cfd0ef 100644
--- a/Dockerfile
+++ b/Dockerfile
@@ -1,4 +1,14 @@
-FROM eclipse-temurin:17-jdk-alpine
-VOLUME /tmp
-COPY target/*.jar /app/hospital-management-api.jar
-ENTRYPOINT ["java", "-jar","/app/hospital-management-api.jar"]
\ No newline at end of file
+# ใช้ JRE เป็น base image เพื่อลดขนาด image
+FROM eclipse-temurin:17-jre-jammy
+
+# กำหนด working directory ภายใน container
+WORKDIR /app
+
+# คัดลอก JAR ไฟล์ที่สร้างขึ้นมาแล้ว
+# โดยต้องปรับชื่อไฟล์ให้ตรงกับชื่อไฟล์ JAR ของคุณ
+# เช่น ถ้าชื่อไฟล์คือ target/hospital-management-api-1.0.jar
+# ก็ใช้ COPY target/hospital-management-api-1.0.jar app.jar
+COPY target/hospital-management-api-1.0.jar app.jar
+
+# สั่งรันแอปพลิเคชันเมื่อ container ทำงาน
+ENTRYPOINT ["java", "-jar", "app.jar"]
diff --git a/README.md b/README.md
index 5803354..d44c792 100644
--- a/README.md
+++ b/README.md
@@ -1,633 +1,286 @@
-# Hospital Management - API Module 
+# Hospital Management API (Extended Version)
-## About the project
-Hospital Management API built in Spring Boot
+
+
-### Prerequisites:
-- Spring Boot 3.2.1
-- JDK 17
-- Maven 4.0.0
+Extended REST API for Hospital Management, built on top of the original project by Mirna Gama. This version includes new features for user management, inventory, and medical records.
-### Running the application
-1. `git clone https://github.com/MirnaGama/hospital-management-api/`
-2. `cd hospital-management-api`
-3. `mvn clean install`
-It will build the jar file in the target folder
-4. `mvn spring-boot:run`
-It will compile and run the application on default port (8080)
+---
-### Running tests
-- `mvn test`
-It will executes all the tests.
+## ✨ Improvements and New Features
-- `mvn -Dtest=packageName.className test`
-It will execute only one test class
+### 1. Code Structure and Architecture
-- `mvn -Dtest=packageName.className#methodName test`
-It will run only one test method from one test class
+* **Entity-Driven Design**: The `UserService` and `AuthServiceImpl` have been refactored to handle user data directly as a `User` entity, making the code cleaner and more aligned with standard Spring Boot practices.
+* **Simplified Registration**: The old `UserDTO` has been replaced with a new `PatientRegistrationDTO`, which combines user and patient information into a single, comprehensive DTO for a smoother registration process.
-### Features - v1.0
-- [X] R1 - Doctor Registration
-- [X] R2 - List of Doctors
-- [X] R3 - Doctor Update
-- [X] R4 - Doctor Exclusion
-- [X] R5 - Patient Registration
-- [X] R6 - List of Patients
-- [X] R7 - Patient Update
-- [X] R8 - Patient Exclusion
-- [X] R9 - Consultation Scheduling
-- [X] R10 - Consultation Cancellation
+### 2. Endpoint and Data Handling Changes
-## API Documentation - /swagger-ui/index.html
+* **New Patient Registration Endpoint**: The old endpoint `POST /api/auth/register` has been replaced with `POST /api/auth/register-patient` to more accurately reflect its function.
+* **Data Integrity Fix**: We fixed a `DataIntegrityViolationException` caused by an overly long `state` value. Test data has been updated to use a 2-character abbreviation (e.g., "CA") to conform to database constraints.
-### authentication
+### 3. Major Test Suite Refinement
-#### POST - [**/api/auth/register**] - Register a new user
+* **Integration Test**: The `AuthenticationControllerTest` has been updated to support the new `PatientRegistrationDTO` and the new `/api/auth/register-patient` endpoint.
+* **Unit Test**: Resolved a `NullPointerException` in `AuthServiceTest` by ensuring each test case runs independently, without relying on shared static variables.
+* **Data Cleanup Order**: Fixed a `Referential integrity constraint violation` by adjusting the data cleanup order in `@AfterAll` to ensure patients are deleted before users.
-- **Body:**
-```
-{
- "login" (string, required),
- "password" (string, required),
-}
+### 4. Additional Features
+
+* Refined the user and patient registration flow.
+* Introduced **RBAC (Role-Based Access Control)** to manage system permissions.
+* Improved the database schema for better data management.
+* Added a **Default Admin** user for easier initial setup.
+
+---
+
+## 🛠 Tech Stack
+- Java 17
+- Spring Boot 3.x
+- PostgreSQL + pgAdmin (via Docker)
+- Spring Security (JWT + RBAC)
+- JUnit 5 & Mockito (Testing)
+- Swagger / OpenAPI
+
+---
+
+## 🚀 Features - v2.0
+
+### Core Data Management
+* **`Doctor`**
+ * [x] **R1** - Doctor Registration
+ * [x] **R2** - Doctor List
+ * [x] **R3** - Doctor Data Update
+ * [x] **R4** - Doctor Data Exclusion
+* **`Patient`**
+ * [x] **R5** - Patient Registration
+ * [x] **R6** - Patient List
+ * [x] **R7** - Patient Data Update
+ * [x] **R8** - Patient Data Exclusion
+* **`Staff`**
+ * [x] **R9** - Staff Creation
+* **`Nurse`**
+ * [x] **R10** - Nurse Registration
+ * [x] **R11** - Nurse List
+ * [x] **R12** - Nurse Data Update
+ * [x] **R13** - Nurse Data Exclusion
+
+### Specialized Management
+* **`Consultation`**
+ * [x] **R14** - Scheduling a Consultation
+ * [x] **R15** - Canceling a Consultation
+ * [x] **R16** - Viewing an Individual Consultation
+* **`Doctor Schedule`**
+ * [x] **R17** - Adding a new Doctor Schedule
+* **`Nurse Schedule`**
+ * [x] **R18** - Adding a new Nurse Schedule
+ * [x] **R19** - Viewing Nurse Schedules (Pagination)
+* **`Operating Room`**
+ * [x] **R20** - Add / Update / Delete Operating Room
+ * [x] **R21** - View Operating Rooms List
+* **`Operating Room Schedule`**
+ * [x] **R22** - Add / View Operating Room Schedules
+* **`Medical Record`**
+ * [x] **R23** - Medical Record Creation
+ * [x] **R24** - Medical Record Update
+ * [x] **R25** - Medical Record Exclusion
+ * [x] **R26** - Viewing a Medical Record by ID
+* **`Prescription`**
+ * [x] **R27** - New Prescription Creation
+* **`Medical Image`**
+ * [x] **R28** - Upload / Download Medical Images
+* **`Lab Result`**
+ * [x] **R29** - Create / View Lab Results by Medical Record ID
+
+### Inventory Management
+* **`Inventory Item`**
+ * [x] **R30** - Inventory Item Creation
+ * [x] **R31** - Inventory Item Update
+ * [x] **R32** - Inventory Item Exclusion
+ * [x] **R33** - Viewing an Inventory Item by ID
+* **`Inventory Transaction`**
+ * [x] **R34** - Inventory Transaction Creation
+* **`Inventory Supplier`**
+ * [x] **R35** - Supplier Creation
+* **`Inventory Item Type`**
+ * [x] **R36** - Item Type Creation
+
+### Insurance Management
+* **`Insurance Provider`**
+ * [x] **R37** - Provider Creation / Update / Delete
+ * [x] **R38** - Viewing Providers List
+* **`Insurance Claim`**
+ * [x] **R39** - Claim Creation / Update / Delete
+ * [x] **R40** - Viewing Claims List
+
+### Billing & Payment
+* **`Billing`**
+ * [x] **R41** - Billing Record Creation / Update / Delete
+ * [x] **R42** - Viewing Billing by ID
+* **`Payment`**
+ * [x] **R43** - Payment Record Creation
+ * [x] **R44** - Viewing all Payment Records
+ * [x] **R45** - Viewing an Individual Payment Record
+
+### Reports
+* **`Inventory Reports`**
+ * [x] **R46** - Low Stock Report
+* **`Financial Reports`**
+ * [x] **R47** - Financial Overview Report
+* **`Appointment Reports`**
+ * [x] **R48** - Appointments Report
+
+### User Management
+* [x] **R49** - Update Username
+* [x] **R50** - Update Password
+* [x] **R51** - Update Role
+* [x] **R52** - Deactivate User Account
+* [x] **R53** - Activate User Account
+* [x] **R54** - Link Patient to User
+* [x] **R55** - Register Nurse and Link
+* [x] **R56** - Register Doctor and Link
+
+---
+
+## 🔑 Default Credentials
+
+For initial administrative access, use the following credentials:
+
+* **Username:** `admin@softwarecraft.tech`
+* **Password:** `pasword123`
+
+---
+
+## 📖 API Endpoints
+
+### 🔑 Authentication (`authentication-controller`)
+* `POST` `/api/auth/register-patient` - Register a new patient
+* `POST` `/api/auth/register-doctor-and-link` - Register a new doctor and link them to a user account
+* `POST` `/api/auth/register-staff` - Register a new staff member
+* `POST` `/api/auth/login` - Log in to the system
+* `POST` `/api/auth/link-patient-to-user` - Link a patient to an existing user account
+
+### 👤 User Management (`user-controller`)
+* `PUT` `/api/v1.0/users/{id}/username` - Update a user's username
+* `PUT` `/api/v1.0/users/{id}/role` - Update a user's role
+* `PUT` `/api/v1.0/users/{id}/password` - Update a user's password
+* `PATCH` `/api/v1.0/users/{id}/deactivate` - Deactivate a user's account
+* `PATCH` `/api/v1.0/users/{id}/activate` - Activate a user's account
+
+### 🧑⚕️ Doctors (`doctor-controller`)
+* `GET` `/api/v1.0/doctors` - Retrieve a list of all doctors
+* `POST` `/api/v1.0/doctors` - Create a new doctor
+* `GET` `/api/v1.0/doctors/{id}` - Retrieve a single doctor by ID
+* `PUT` `/api/v1.0/doctors` - Update an existing doctor
+* `DELETE` `/api/v1.0/doctors/{id}` - Delete a doctor by ID
+
+### 🤒 Patients (`patient-controller`)
+* `GET` `/api/v1.0/patients` - Retrieve a list of all patients
+* `POST` `/api/v1.0/patients` - Create a new patient
+* `GET` `/api/v1.0/patients/{id}` - Retrieve a single patient by ID
+* `PUT` `/api/v1.0/patients` - Update an existing patient
+* `DELETE` `/api/v1.0/patients/{id}` - Delete a patient by ID
+
+### 🏥 Staff (`staff-controller`)
+* `POST` `/api/v1.0/staff` - Add a new staff member
+
+### 🩺 Consultations (`consultation-controller`)
+* `POST` `/api/v1.0/consultations` - Create a new consultation
+* `GET` `/api/v1.0/consultations/{id}` - Retrieve a consultation by ID
+* `DELETE` `/api/v1.0/consultations` - Cancel a consultation
+
+### 📆 Doctor Schedules (`doctor-schedules-controller`)
+* `POST` `/api/v1.0/doctor-schedules` - Add a new doctor schedule
+
+### 📝 Medical Records (`medical-record-controller`)
+* `POST` `/api/v1.0/medical-records` - Create a new medical record
+* `GET` `/api/v1.0/medical-records/{id}` - Retrieve a medical record by ID
+* `PUT` `/api/v1.0/medical-records/{id}` - Update a medical record
+* `DELETE` `/api/v1.0/medical-records/{id}` - Delete a medical record
+
+### 💊 Prescriptions (`prescriptions-controller`)
+* `POST` `/api/v1.0/prescriptions` - Create a new prescription
+
+### 💲 Payments (`payment-controller`)
+* `POST` `/api/v1.0/payments` - Create a new payment record
+* `GET` `/api/v1.0/payments` - Retrieve all payment records
+* `GET` `/api/v1.0/payments/{id}` - Retrieve a single payment record by ID
+
+### 📦 Inventory (`inventory-controller`)
+* `POST` `/api/v1.0/inventory/items` - Create a new inventory item
+* `GET` `/api/v1.0/inventory/items/{id}` - Retrieve an inventory item by ID
+* `PUT` `/api/v1.0/inventory/items/{id}` - Update an inventory item
+* `DELETE` `/api/v1.0/inventory/items/{id}` - Delete an inventory item
+* `POST` `/api/v1.0/inventory/transactions` - Create a new inventory transaction
+* `POST` `/api/v1.0/inventory/suppliers` - Create a new supplier
+* `POST` `/api/v1.0/inventory/item-types` - Create a new inventory item type
+
+---
+
+## 🚀 How to Run
+
+### 1️⃣ Clone the Repository
+```bash
+git clone
+cd hospital-management-api
```
-- **Responses:**
+### 2️⃣ Set Environment Variables for IntelliJ
-| Code | Description |
-| ------------- | ------------- |
-| `200` | _Successful operation_ |
-| `400` | _Validation Error_ |
+เปิด IntelliJ → ไปที่ Run → Edit Configurations
-#### POST - [**/api/auth/login**] - Perform the login
+เลือก Configuration ของ Spring Boot ของโปรเจค
-- **Body:**
+ในส่วน Environment Variables กำหนดค่าตามนี้:
```
-{
- "login" (string, required),
- "password" (string, required),
-}
+POSTGRES_HOST=localhost
+POSTGRES_PORT=5432
+POSTGRES_DB=
+POSTGRES_USER=
+POSTGRES_PASSWORD=
+JWT_SECRET=
+MINIO_URL=
+MINIO_ACCESS=
+MINIO_SECRET=
+MINIO_BUCKET=
+PGADMIN_DEFAULT_EMAIL=
+PGADMIN_DEFAULT_PASSWORD=
```
-- **Responses:**
-
-| Code | Description |
-| ------------- | ------------- |
-| `200` | _Successful operation_ |
-| `400` | _Validation Error_ |
-| `403` | _Incorrect credentials_ |
-
-
-### doctors
-
-#### POST - [**/api/v1.0/doctors**] - Adds a new doctor
-
-- **Body:**
+### 3️⃣ Run PostgreSQL and pgAdmin
```
-{
- "name" (string, required),
- "email" (string, required),
- "crm" (string, required),
- "telephone" (string, required),
- "specialty" (string, required),
- "address": {
- "street" (string, required),
- "neighborhood" (string, required),
- "zipCode" (string, required),
- "city" (string, required),
- "state" (string, required),
- "additionalDetails" (string, optional),
- "houseNumber" (string, optional)
- }
-}
+# รันเฉพาะ PostgreSQL และ pgAdmin
+docker-compose up -d postgresdb pgadmin
+
```
-- **Request Headers:**
+### 4️⃣ Run Spring Boot Application
-| Key | Description |
-| ------------- | ------------- |
-| `Authorization` | _Authorization token_ |
+เปิด IntelliJ
-- **Responses:**
+Run Spring Boot จาก Configuration ที่ตั้งค่า Environment Variables แล้ว
-| Code | Description |
-| ------------- | ------------- |
-| `201` | _Successfully created_ |
-| `400` | _Validation Error_ |
-| `403` | _Unauthorized / Invalid token_ |
+✅ แอปจะเชื่อมต่อ PostgreSQL และ MinIO ตามค่าที่กำหนด
-#### GET - [**/api/v1.0/doctors/{id}**] - Get an existing doctor
+---
-- **Response Body Example:**
-```
-{
- "id": 1,
- "name": "DOCTOR TEST",
- "email": "test@gmail.com",
- "crm": "12456",
- "telephone": "(81) 99999999",
- "specialty": "ORTHOPEDICS",
- "active": true,
- "address": {
- "street": "TEST STR.",
- "neighborhood": "TEST NEIGHBORHOOD",
- "zipCode": "12345678",
- "city": "TEST CITY",
- "state": "ST",
- "additionalDetails": null,
- "houseNumber": null
- }
-}
-```
+### Future Development Plan (v2.1+)
-- **Request Headers:**
+We will continue to develop on Spring Boot following standard best practices to add the following capabilities:
-| Key | Description |
-| ------------- | ------------- |
-| `Authorization` | _Authorization token_ |
+**AI-Driven Enhancements**
+- Implement predictive analytics for patient admissions and resource allocation.
+- Integrate AI models for anomaly detection in lab results or vital signs.
+- Use Natural Language Processing (NLP) for automated parsing of medical notes.
+- Suggest treatment plans or risk alerts based on historical patient data.
+---
-- **Request Parameters:**
+## 📝 API Documentation
+Full API documentation (Swagger UI) is available at:
+https://his-backend.softwarecraft.tech/swagger-ui/index.html
-| Key | Description |
-| ------------- | ------------- |
-| `id` | _Unique identifier of the doctor who will be fetched_ |
+---
-- **Responses:**
-
-| Code | Description |
-| ------------- | ------------- |
-| `200` | _Successful operation_ |
-| `404` | _Entity not found_ |
-| `403` | _Unauthorized / Invalid token_ |
-
-#### GET - [**/api/v1.0/doctors**] - Get a list of doctors
-
-- **Response Body Example:**
-```
-{
- "content": [
- {
- "name": "Test1",
- "email": "test1@gmail.com",
- "crm": "123456",
- "specialty": "ORTHOPEDICS"
- },
- {
- "name": "Test2",
- "email": "test2@gmail.com",
- "crm": "789101",
- "specialty": "ORTHOPEDICS"
- },
- {
- "name": "Test3",
- "email": "test3@gmail.com",
- "crm": "112131",
- "specialty": "ORTHOPEDICS"
- },
- ],
- "pageable": {
- "pageNumber": 0,
- "pageSize": 10,
- "sort": {
- "sorted": true,
- "unsorted": false,
- "empty": false
- },
- "offset": 0,
- "paged": true,
- "unpaged": false
- },
- "totalPages": 1,
- "totalElements": 3,
- "last": true,
- "sort": {
- "sorted": true,
- "unsorted": false,
- "empty": false
- },
- "number": 0,
- "size": 10,
- "first": true,
- "numberOfElements": 3,
- "empty": false
-}
-```
-
-- **Request Headers:**
-
-| Key | Description |
-| ------------- | ------------- |
-| `Authorization` | _Authorization token_ |
-
-- **Request Parameters:**
-
-| Key | Description |
-| ------------- | ------------- |
-| `size` | _Number of records that should be returned_ |
-| `sort` | _Sort by object attribute in descending order_ |
-| `page` | _Page number_ |
-
-- **Responses:**
-
-| Code | Description |
-| ------------- | ------------- |
-| `200` | _Successful operation_ |
-| `403` | _Unauthorized / Invalid token_ |
-
-
-#### PUT - [**/api/v1.0/doctors**] - Updates an existing doctor
-
-- **Body:**
-```
-{
- "id" (number, required),
- "name" (string, optional),
- "telephone" (string, optional),
- "address": {
- "street" (string, optional),
- "neighborhood" (string, optional),
- "zipcode" (string, optional),
- "city" (string, optional),
- "state" (string, optional),
- "additionalDetails" (string, optional),
- "houseNumber" (string, optional),
- }
-}
-```
-
-- **Request Headers:**
-
-| Key | Description |
-| ------------- | ------------- |
-| `Authorization` | _Authorization token_ |
-
-- **Responses:**
-
-| Code | Description |
-| ------------- | ------------- |
-| `200` | _Successful operation_ |
-| `400` | _Validation Error_ |
-| `403` | _Unauthorized / Invalid token_ |
-
-
-#### DELETE - [**/api/v1.0/doctors/{id}**] - Deactivates an existing doctor
-
-- **Response Body Example:**
-```
-{
- "id": 2,
- "name": "DEACTIVATED DOCTOR TEST",
- "email": "test@gmail.com",
- "crm": "12456",
- "telephone": "(81) 99999999",
- "specialty": "ORTHOPEDICS",
- "active": false,
- "address": {
- "street": "TEST STR.",
- "neighborhood": "TEST NEIGHBORHOOD",
- "zipCode": "12345678",
- "city": "TEST CITY",
- "state": "ST",
- "additionalDetails": null,
- "houseNumber": null
- }
-}
-```
-
-- **Request Headers:**
-
-| Key | Description |
-| ------------- | ------------- |
-| `Authorization` | _Authorization token_ |
-
-- **Request Parameters:**
-
-| Key | Description |
-| ------------- | ------------- |
-| `id` | _Unique identifier of the doctor who will be deactivated_ |
-
-- **Responses:**
-
-| Code | Description |
-| ------------- | ------------- |
-| `200` | _Successful operation_ |
-| `400` | _Validation Error_ |
-| `404` | _Entity not found_ |
-| `403` | _Unauthorized / Invalid token_ |
-
-### patients
-
-#### POST - [**/api/v1.0/patients**] - Adds a new patient
-
-- **Body:**
-```
-{
- "name" (string, required),
- "email" (string, required),
- "cpf" (string, required),
- "telephone" (string, required),
- "address": {
- "street" (string, required),
- "neighborhood" (string, required),
- "zipCode" (string, required),
- "city" (string, required),
- "state" (string, required),
- "additionalDetails" (string, optional),
- "houseNumber" (string, optional)
- }
-}
-```
-
-- **Request Headers:**
-
-| Key | Description |
-| ------------- | ------------- |
-| `Authorization` | _Authorization token_ |
-
-- **Responses:**
-
-| Code | Description |
-| ------------- | ------------- |
-| `201` | _Successfully created_ |
-| `400` | _Validation Error_ |
-| `403` | _Unauthorized / Invalid token_ |
-
-
-#### GET - [**/api/v1.0/patients/{id}**] - Get an existing patient
-
-- **Response Body Example:**
-```
-{
- "id": 1,
- "name": "PATIENT TEST",
- "email": "test@gmail.com",
- "cpf": "11111111111",
- "telephone": "(81) 99999999",
- "active": true,
- "address": {
- "street": "TEST STR.",
- "neighborhood": "TEST NEIGHBORHOOD",
- "zipCode": "12345678",
- "city": "TEST CITY",
- "state": "ST",
- "additionalDetails": null,
- "houseNumber": null
- }
-}
-```
-
-- **Request Headers:**
-
-| Key | Description |
-| ------------- | ------------- |
-| `Authorization` | _Authorization token_ |
-
-- **Request Parameters:**
-
-| Key | Description |
-| ------------- | ------------- |
-| `id` | _Unique identifier of the patient who will be fetched_ |
-
-- **Responses:**
-
-| Code | Description |
-| ------------- | ------------- |
-| `200` | _Successful operation_ |
-| `404` | _Entity not found_ |
-| `403` | _Unauthorized / Invalid token_ |
-
-#### GET - [**/api/v1.0/patients**] - Get a list of patients
-
-- **Response Body Example:**
-```
-{
- "content": [
- {
- "name": "Test1",
- "email": "test1@gmail.com",
- "cpf": "123456"
- },
- {
- "name": "Test2",
- "email": "test2@gmail.com",
- "cpf": "789101"
- },
- {
- "name": "Test3",
- "email": "test3@gmail.com",
- "cpf": "112131"
- },
- ],
- "pageable": {
- "pageNumber": 0,
- "pageSize": 10,
- "sort": {
- "sorted": true,
- "unsorted": false,
- "empty": false
- },
- "offset": 0,
- "paged": true,
- "unpaged": false
- },
- "totalPages": 1,
- "totalElements": 3,
- "last": true,
- "sort": {
- "sorted": true,
- "unsorted": false,
- "empty": false
- },
- "number": 0,
- "size": 10,
- "first": true,
- "numberOfElements": 3,
- "empty": false
-}
-```
-
-- **Request Headers:**
-
-| Key | Description |
-| ------------- | ------------- |
-| `Authorization` | _Authorization token_ |
-
-- **Request Parameters:**
-
-| Key | Description |
-| ------------- | ------------- |
-| `size` | _Number of records that should be returned_ |
-| `sort` | _Sort by object attribute in descending order_ |
-| `page` | _Page number_ |
-
-- **Responses:**
-
-| Code | Description |
-| ------------- | ------------- |
-| `200` | _Successful operation_ |
-| `403` | _Unauthorized / Invalid token_ |
-
-#### PUT - [**/api/v1.0/patients**] - Updates an existing patient
-
-- **Body:**
-```
-{
- "id" (number, required),
- "name" (string, optional),
- "telephone" (string, optional),
- "address": {
- "street" (string, optional),
- "neighborhood" (string, optional),
- "zipcode" (string, optional),
- "city" (string, optional),
- "state" (string, optional),
- "additionalDetails" (string, optional),
- "houseNumber" (string, optional),
- }
-}
-```
-
-- **Request Headers:**
-
-| Key | Description |
-| ------------- | ------------- |
-| `Authorization` | _Authorization token_ |
-
-- **Responses:**
-
-| Code | Description |
-| ------------- | ------------- |
-| `200` | _Successful operation_ |
-| `400` | _Validation Error_ |
-| `403` | _Unauthorized / Invalid token_ |
-
-#### DELETE - [**/api/v1.0/patients/{id}**] - Deactivates an existing patient
-
-- **Response Body Example:**
-```
-{
- "id": 1,
- "name": "DEACTIVATED PATIENT TEST",
- "email": "test@gmail.com",
- "cpf": "11111111111",
- "telephone": "(81) 99999999",
- "active": false,
- "address": {
- "street": "TEST STR.",
- "neighborhood": "TEST NEIGHBORHOOD",
- "zipCode": "12345678",
- "city": "TEST CITY",
- "state": "ST",
- "additionalDetails": null,
- "houseNumber": null
- }
-}
-```
-
-- **Request Headers:**
-
-| Key | Description |
-| ------------- | ------------- |
-| `Authorization` | _Authorization token_ |
-
-- **Request Parameters:**
-
-| Key | Description |
-| ------------- | ------------- |
-| `id` | _Unique identifier of the patient who will be deactivated_ |
-
-- **Responses:**
-
-| Code | Description |
-| ------------- | ------------- |
-| `200` | _Successful operation_ |
-| `400` | _Validation Error_ |
-| `404` | _Entity not found_ |
-| `403` | _Unauthorized / Invalid token_ |
-
-### consultations
-
-#### POST - [**/api/v1.0/consultations**] - Adds a new consultation
-
-- **Body:**
-```
-{
- "patientId" (number, required),
- "consultationDate" (string, required),
- "doctorId" (number, required if _specialty_ field is not filled),
- "specialty" (string, required if _doctorId_ field is not filled)
-}
-```
-
-- **Request Headers:**
-
-| Key | Description |
-| ------------- | ------------- |
-| `Authorization` | _Authorization token_ |
-
-- **Responses:**
-
-| Code | Description |
-| ------------- | ------------- |
-| `201` | _Successfully created_ |
-| `400` | _Validation Error_ |
-| `403` | _Unauthorized / Invalid token_ |
-| `404` | _Entity not found_ |
-
-#### GET - [**/api/v1.0/consultations/{id}**] - Get an existing consultation
-
-- **Response Body Example:**
-```
-{
- "id": 1,
- "consultationDate": "22/04/2024 10:34",
- "patient": {...},
- "doctor": {...},
- "canceled": false,
- "reasonCancellation: ""
-}
-```
-
-- **Request Headers:**
-
-| Key | Description |
-| ------------- | ------------- |
-| `Authorization` | _Authorization token_ |
-
-- **Request Parameters:**
-
-| Key | Description |
-| ------------- | ------------- |
-| `id` | _Unique identifier of the consultation that will be fetched_ |
-
-- **Responses:**
-
-| Code | Description |
-| ------------- | ------------- |
-| `200` | _Successful operation_ |
-| `404` | _Entity not found_ |
-| `403` | _Unauthorized / Invalid token_ |
-
-#### DELETE - [**/api/v1.0/consultations**] - Cancels a scheduled consultation
-
-- **Body:**
-```
-{
- "consultationId" (number, required),
- "reasonCancellation" (string, required),
-}
-```
-
-- **Request Headers:**
-
-| Key | Description |
-| ------------- | ------------- |
-| `Authorization` | _Authorization token_ |
-
-- **Responses:**
-
-| Code | Description |
-| ------------- | ------------- |
-| `200` | _Successful operation_ |
-| `403` | _Unauthorized / Invalid token_ |
-| `404` | _Entity not found_ |
+## 🙏 Credits
+Extended version of MirnaGama/hospital-management-api.
+This continuation improves code quality, adds features, and addresses real-world issues.
\ No newline at end of file
diff --git a/docker-compose.yml b/docker-compose.yml
new file mode 100644
index 0000000..8d28a9f
--- /dev/null
+++ b/docker-compose.yml
@@ -0,0 +1,51 @@
+version: '3.8'
+
+services:
+ postgresdb:
+ image: postgres:13
+ container_name: postgres-hospital
+ restart: always
+ environment:
+ POSTGRES_USER: ${POSTGRES_USER}
+ POSTGRES_PASSWORD: ${POSTGRES_PASSWORD}
+ POSTGRES_DB: ${POSTGRES_DB}
+ ports:
+ - '5432:5432'
+ volumes:
+ - postgres-data:/var/lib/postgresql/data
+
+ api:
+ image: adminsoftwarecraft/hospital-api:v1.0.0
+ container_name: hospital-api-container
+ restart: on-failure
+ environment:
+ SPRING_DATASOURCE_URL: jdbc:postgresql://postgresdb:5432/${POSTGRES_DB}
+ SPRING_DATASOURCE_USERNAME: ${POSTGRES_USER}
+ SPRING_DATASOURCE_PASSWORD: ${POSTGRES_PASSWORD}
+ JWT_SECRET: ${JWT_SECRET}
+ MINIO_URL: ${MINIO_URL}
+ MINIO_ACCESS: ${MINIO_ACCESS}
+ MINIO_SECRET: ${MINIO_SECRET}
+ MINIO_BUCKET: ${MINIO_BUCKET}
+ ports:
+ - "8080:8080"
+ depends_on:
+ - postgresdb
+
+ pgadmin:
+ image: dpage/pgadmin4
+ container_name: pgadmin-hospital
+ restart: always
+ environment:
+ PGADMIN_DEFAULT_EMAIL: ${PGADMIN_DEFAULT_EMAIL}
+ PGADMIN_DEFAULT_PASSWORD: ${PGADMIN_DEFAULT_PASSWORD}
+ ports:
+ - '8180:80'
+ volumes:
+ - pgadmin-data:/var/lib/pgadmin
+ depends_on:
+ - postgresdb
+
+volumes:
+ postgres-data:
+ pgadmin-data:
diff --git a/pom.xml b/pom.xml
index 760583b..b6d0325 100644
--- a/pom.xml
+++ b/pom.xml
@@ -40,23 +40,37 @@
org.springframework.boot
spring-boot-starter-validation
+
+ org.projectlombok
+ lombok
+ 1.18.30
+ provided
+
+
- org.flywaydb
- flyway-core
-
-
- org.flywaydb
- flyway-mysql
-
-
- com.mysql
- mysql-connector-j
+ org.postgresql
+ postgresql
runtime
+
+
+
+ org.flywaydb
+ flyway-core
+ 9.22.3
+
+
+
+
+ io.minio
+ minio
+ 8.5.2
+
+
com.h2database
h2
- 2.1.214
+ 2.2.220
org.springframework.boot
diff --git a/src/main/java/com/mirna/hospitalmanagementapi/application/controllers/BillingController.java b/src/main/java/com/mirna/hospitalmanagementapi/application/controllers/BillingController.java
new file mode 100644
index 0000000..ff3f244
--- /dev/null
+++ b/src/main/java/com/mirna/hospitalmanagementapi/application/controllers/BillingController.java
@@ -0,0 +1,49 @@
+package com.mirna.hospitalmanagementapi.application.controllers;
+
+import com.mirna.hospitalmanagementapi.domain.entities.Billing;
+import com.mirna.hospitalmanagementapi.domain.dtos.BillingDTO;
+import com.mirna.hospitalmanagementapi.domain.services.BillingService;
+import io.swagger.v3.oas.annotations.security.SecurityRequirement;
+import jakarta.validation.Valid;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.http.HttpStatus;
+import org.springframework.http.ResponseEntity;
+import org.springframework.web.bind.annotation.*;
+import org.springframework.web.util.UriComponentsBuilder;
+import java.net.URI;
+import org.springframework.security.access.prepost.PreAuthorize;
+
+@RestController
+@RequestMapping("/api/v1.0/billings")
+@SecurityRequirement(name = "bearer-key")
+public class BillingController {
+
+ @Autowired
+ private BillingService billingService;
+
+ @PostMapping
+ public ResponseEntity createBilling(@RequestBody @Valid BillingDTO billingDTO, UriComponentsBuilder uriBuilder) {
+ Billing newBilling = billingService.createBilling(billingDTO);
+ URI uri = uriBuilder.path("/api/v1.0/billings/{id}").buildAndExpand(newBilling.getId()).toUri();
+ return ResponseEntity.created(uri).body(newBilling);
+ }
+
+ @GetMapping("/{id}")
+ @PreAuthorize("hasAnyRole('ADMIN', 'RECEPTIONIST') or (hasRole('PATIENT') and @billingServiceImpl.isOwner(#id, authentication.principal.id))")
+ public ResponseEntity getBillingById(@PathVariable Long id) {
+ Billing billing = billingService.getBillingById(id);
+ return ResponseEntity.ok(billing);
+ }
+
+ @PutMapping("/{id}")
+ public ResponseEntity updateBilling(@PathVariable Long id, @RequestBody @Valid BillingDTO billingDTO) {
+ Billing updatedBilling = billingService.updateBilling(id, billingDTO);
+ return ResponseEntity.ok(updatedBilling);
+ }
+
+ @DeleteMapping("/{id}")
+ public ResponseEntity deleteBilling(@PathVariable Long id) {
+ billingService.deleteBilling(id);
+ return ResponseEntity.noContent().build();
+ }
+}
\ No newline at end of file
diff --git a/src/main/java/com/mirna/hospitalmanagementapi/application/controllers/ConsultationController.java b/src/main/java/com/mirna/hospitalmanagementapi/application/controllers/ConsultationController.java
index f42e126..11fdc9b 100644
--- a/src/main/java/com/mirna/hospitalmanagementapi/application/controllers/ConsultationController.java
+++ b/src/main/java/com/mirna/hospitalmanagementapi/application/controllers/ConsultationController.java
@@ -21,6 +21,10 @@ import com.mirna.hospitalmanagementapi.domain.entities.Consultation;
import com.mirna.hospitalmanagementapi.domain.exceptions.ConsultationValidationException;
import com.mirna.hospitalmanagementapi.domain.services.ConsultationService;
+import io.swagger.v3.oas.annotations.Operation;
+import io.swagger.v3.oas.annotations.media.Content;
+import io.swagger.v3.oas.annotations.media.ExampleObject;
+import io.swagger.v3.oas.annotations.responses.ApiResponse;
import io.swagger.v3.oas.annotations.security.SecurityRequirement;
import jakarta.validation.Valid;
@@ -35,59 +39,84 @@ import jakarta.validation.Valid;
@SecurityRequirement(name = "bearer-key")
public class ConsultationController {
- @Autowired
- private ConsultationService consultationService;
-
- /**
- * Post method to create a new Consultation object based on the provided DTO.
- *
- * @param consultationDTO The data transfer object containing data for Consultation
- * entity.
- *
- * @return A response entity containing the saved consultation and created status if successful, or
- * a 400-level error if there is a validation error
- * @throws ConsultationValidationException if there is a validation error
- */
- @PostMapping
- public ResponseEntity