diff --git a/backend/Dockerfile b/backend/Dockerfile
index 9a0dcdb..25752c6 100644
--- a/backend/Dockerfile
+++ b/backend/Dockerfile
@@ -1,15 +1,21 @@
-# Build stage
+# Build stage ---------------------------------------------------------------
FROM maven:3.9.12-eclipse-temurin-25 AS build
WORKDIR /app
COPY pom.xml .
COPY src ./src
RUN mvn clean package
-# Run stage
+# Run stage ---------------------------------------------------------------
FROM eclipse-temurin:25-jre
WORKDIR /app
ARG APP_VERSION=dev
ENV APP_VERSION=${APP_VERSION}
+
+# Install curl (required for the health‑check)
+RUN apt-get update && \
+ apt-get install -y curl && \
+ rm -rf /var/lib/apt/lists/*
+
COPY --from=build /app/target/*.jar app.jar
-EXPOSE 8080
+EXPOSE 8082
ENTRYPOINT ["java", "-jar", "app.jar"]
diff --git a/backend/pom.xml b/backend/pom.xml
index 0393658..c074245 100644
--- a/backend/pom.xml
+++ b/backend/pom.xml
@@ -65,6 +65,10 @@
spring-boot-starter-webmvc-test
test
+
+ org.springframework.boot
+ spring-boot-starter-actuator
+
diff --git a/backend/src/main/java/com/todo/backend/config/WebConfig.java b/backend/src/main/java/com/todo/backend/config/WebConfig.java
index 9ab638b..6123059 100644
--- a/backend/src/main/java/com/todo/backend/config/WebConfig.java
+++ b/backend/src/main/java/com/todo/backend/config/WebConfig.java
@@ -10,8 +10,7 @@ public class WebConfig implements WebMvcConfigurer {
@Override
public void addCorsMappings(CorsRegistry registry) {
registry.addMapping("/**")
- .allowedOrigins("http://localhost:5173", "http://localhost:3000", "http://localhost:8081",
- "http://localhost:80", "https://todo.almazlar.com") // Typical Vite/React/Docker ports
+ .allowedOrigins("http://localhost:5173", "https://todo.almazlar.com")
.allowedMethods("GET", "POST", "PUT", "DELETE", "OPTIONS")
.allowedHeaders("*")
.allowCredentials(true);
diff --git a/backend/src/main/java/com/todo/backend/controller/VersionController.java b/backend/src/main/java/com/todo/backend/controller/VersionController.java
index 78f1ec3..6e643a4 100644
--- a/backend/src/main/java/com/todo/backend/controller/VersionController.java
+++ b/backend/src/main/java/com/todo/backend/controller/VersionController.java
@@ -10,7 +10,7 @@ import java.util.HashMap;
import java.util.Map;
@RestController
-@RequestMapping("/api/version")
+@RequestMapping("/version")
public class VersionController {
@Value("${APP_VERSION:dev}")
diff --git a/backend/src/main/resources/application.properties b/backend/src/main/resources/application.properties
index 56d4a2d..3ccaa72 100644
--- a/backend/src/main/resources/application.properties
+++ b/backend/src/main/resources/application.properties
@@ -1,9 +1,11 @@
+# backend/src/main/resources/application.properties
+
server.port=8082
server.servlet.context-path=/api
spring.application.name=backend
-spring.datasource.url=jdbc:postgresql://localhost:5432/tododb
-spring.datasource.username=postgres
-spring.datasource.password=postgres
+
spring.jpa.hibernate.ddl-auto=update
spring.jpa.show-sql=true
spring.jpa.properties.hibernate.dialect=org.hibernate.dialect.PostgreSQLDialect
+management.endpoints.web.exposure.include=health,info,metrics
+management.endpoint.health.show-details=always
\ No newline at end of file
diff --git a/backend/src/test/java/com/todo/backend/controller/TodoControllerTest.java b/backend/src/test/java/com/todo/backend/controller/TodoControllerTest.java
index 80ae3a5..e09979a 100644
--- a/backend/src/test/java/com/todo/backend/controller/TodoControllerTest.java
+++ b/backend/src/test/java/com/todo/backend/controller/TodoControllerTest.java
@@ -7,6 +7,7 @@ import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.webmvc.test.autoconfigure.WebMvcTest;
+import org.springframework.test.context.ActiveProfiles;
// Spring Boot 3.4+ replaces @MockBean with @MockitoBean
import org.springframework.test.context.bean.override.mockito.MockitoBean;
import org.springframework.http.MediaType;
@@ -25,6 +26,7 @@ import static org.springframework.test.web.servlet.request.MockMvcRequestBuilder
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.*;
@WebMvcTest(TodoController.class)
+@ActiveProfiles("test")
public class TodoControllerTest {
@Autowired
@@ -52,7 +54,7 @@ public class TodoControllerTest {
List todos = Arrays.asList(todo1, todo2);
when(todoService.getAllTodos()).thenReturn(todos);
- mockMvc.perform(get("/api/todos"))
+ mockMvc.perform(get("/todos"))
.andExpect(status().isOk())
.andExpect(jsonPath("$", hasSize(2)))
.andExpect(jsonPath("$[0].title", is(todo1.getTitle())))
@@ -63,7 +65,7 @@ public class TodoControllerTest {
void getTodoById_WhenExists_ReturnsTodo() throws Exception {
when(todoService.getTodoById(1L)).thenReturn(Optional.of(todo1));
- mockMvc.perform(get("/api/todos/1"))
+ mockMvc.perform(get("/todos/1"))
.andExpect(status().isOk())
.andExpect(jsonPath("$.title", is(todo1.getTitle())))
.andExpect(jsonPath("$.id", is(1)));
@@ -73,7 +75,7 @@ public class TodoControllerTest {
void getTodoById_WhenNotExists_ReturnsNotFound() throws Exception {
when(todoService.getTodoById(99L)).thenReturn(Optional.empty());
- mockMvc.perform(get("/api/todos/99"))
+ mockMvc.perform(get("/todos/99"))
.andExpect(status().isNotFound());
}
@@ -85,7 +87,7 @@ public class TodoControllerTest {
when(todoService.createTodo(any(Todo.class))).thenReturn(savedTodo);
- mockMvc.perform(post("/api/todos")
+ mockMvc.perform(post("/todos")
.contentType(MediaType.APPLICATION_JSON)
.content(objectMapper.writeValueAsString(newTodo)))
.andExpect(status().isCreated())
@@ -101,7 +103,7 @@ public class TodoControllerTest {
when(todoService.updateTodo(eq(1L), any(Todo.class))).thenReturn(updatedTodo);
- mockMvc.perform(put("/api/todos/1")
+ mockMvc.perform(put("/todos/1")
.contentType(MediaType.APPLICATION_JSON)
.content(objectMapper.writeValueAsString(updatedInfo)))
.andExpect(status().isOk())
@@ -115,7 +117,7 @@ public class TodoControllerTest {
when(todoService.updateTodo(eq(99L), any(Todo.class))).thenReturn(null);
- mockMvc.perform(put("/api/todos/99")
+ mockMvc.perform(put("/todos/99")
.contentType(MediaType.APPLICATION_JSON)
.content(objectMapper.writeValueAsString(updatedInfo)))
.andExpect(status().isNotFound());
@@ -125,7 +127,7 @@ public class TodoControllerTest {
void deleteTodo_WhenExists_ReturnsNoContent() throws Exception {
when(todoService.deleteTodo(1L)).thenReturn(true);
- mockMvc.perform(delete("/api/todos/1"))
+ mockMvc.perform(delete("/todos/1"))
.andExpect(status().isNoContent());
}
@@ -133,7 +135,9 @@ public class TodoControllerTest {
void deleteTodo_WhenNotExists_ReturnsNotFound() throws Exception {
when(todoService.deleteTodo(99L)).thenReturn(false);
- mockMvc.perform(delete("/api/todos/99"))
+ mockMvc.perform(delete("/todos/99"))
.andExpect(status().isNotFound());
}
}
+
+
diff --git a/backend/src/test/resources/application-test.properties b/backend/src/test/resources/application-test.properties
index 5ba45fc..729d148 100644
--- a/backend/src/test/resources/application-test.properties
+++ b/backend/src/test/resources/application-test.properties
@@ -4,3 +4,4 @@ spring.datasource.username=sa
spring.datasource.password=
spring.jpa.database-platform=org.hibernate.dialect.H2Dialect
spring.jpa.hibernate.ddl-auto=create-drop
+spring.jpa.properties.hibernate.dialect=org.hibernate.dialect.H2Dialect
\ No newline at end of file
diff --git a/docker-compose.yml b/docker-compose.yml
index e3d49ce..8b245ba 100644
--- a/docker-compose.yml
+++ b/docker-compose.yml
@@ -22,7 +22,7 @@ services:
build: ./backend
container_name: todo-backend
ports:
- - "8082:8080"
+ - "8082:8082"
environment:
- SPRING_DATASOURCE_URL=jdbc:postgresql://db:5432/tododb
- SPRING_DATASOURCE_USERNAME=postgres
@@ -31,7 +31,7 @@ services:
db:
condition: service_healthy
healthcheck:
- test: ["CMD-SHELL", "curl -f http://localhost:8080/actuator/health || exit 1"]
+ test: ["CMD-SHELL", "curl -f http://localhost:8082/api/actuator/health || exit 1"]
interval: 10s
timeout: 5s
retries: 5
@@ -43,7 +43,8 @@ services:
ports:
- "5173:80"
depends_on:
- - backend
+ backend:
+ condition: service_healthy
volumes: