Skip to content

Feature/backend skeleton#2

Open
gostev-p wants to merge 7 commits intomainfrom
feature/backend-skeleton
Open

Feature/backend skeleton#2
gostev-p wants to merge 7 commits intomainfrom
feature/backend-skeleton

Conversation

@gostev-p
Copy link
Copy Markdown

This pull request sets up the initial backend foundation for the Policy Hub application using Spring Boot. It introduces the project structure, build configuration, essential tooling, and basic application scaffolding, including configuration for OpenAPI, Jackson, and global exception handling. The changes also add developer documentation and environment setup files.

The most important changes are:

Project Setup & Tooling:

  • Added Gradle build configuration with Java 21, Spring Boot 3.5, and dependencies for JPA, Security, Validation, OpenAPI, H2, PostgreSQL, and Flyway. Included Gradle wrapper scripts and properties for cross-platform builds. (build.gradle.kts, settings.gradle.kts, gradlew, gradlew.bat, gradle-wrapper.properties) [1] [2] [3] [4] [5]
  • Added .gitignore and .gitattributes files to manage IDE, build, and binary artifacts, ensuring a clean repository. [1] [2]

Documentation:

  • Created a comprehensive README.md with setup instructions, project structure, endpoints, authentication details, and technology stack, tailored for developer onboarding.

Core Application Bootstrapping:

  • Added the main Spring Boot entry point in PolicyHubApplication.java.
  • Introduced configuration classes for OpenAPI (OpenApiConfig.java) and Jackson (JacksonConfig.java) for API documentation and JSON serialization. [1] [2]

Error Handling:

  • Implemented a global exception handler (GlobalExceptionHandler.java) and a standardized error response model (ErrorResponse.java) for consistent API error reporting. [1] [2]

@gostev-p gostev-p requested review from MarioH91 and Copilot March 27, 2026 12:02
@gostev-p gostev-p self-assigned this Mar 27, 2026
@gostev-p gostev-p added the feature A new feature request label Mar 27, 2026
Copy link
Copy Markdown

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Initial Spring Boot backend scaffolding for the Policy Hub application, including build tooling (Gradle), baseline configuration (profiles/logging/OpenAPI/Jackson), security defaults, global error handling, and a skeleton “policies” endpoint with basic tests.

Changes:

  • Added Gradle-based Spring Boot (Java 21) project setup with wrapper, dependencies, and basic README/onboarding docs.
  • Introduced baseline runtime configuration (dev/prod profiles, Logback, OpenAPI, Jackson) plus global exception handling.
  • Implemented initial security config and a skeleton /api/v1/policies endpoint with MVC tests.

Reviewed changes

Copilot reviewed 26 out of 30 changed files in this pull request and generated 7 comments.

Show a summary per file
File Description
backend/src/test/java/org/constructx/policyhub/policies/api/PolicyControllerTest.java MVC slice test for policies endpoint with/without authentication
backend/src/test/java/org/constructx/policyhub/PolicyHubApplicationTests.java Spring context smoke test
backend/src/main/resources/templates/.gitattribute Empty placeholder file to keep templates dir
backend/src/main/resources/static/.gitattribute Empty placeholder file to keep static dir
backend/src/main/resources/logback-spring.xml Logback config with dev/prod profiles
backend/src/main/resources/db/migration/.gitattribute Empty placeholder file to keep migration dir
backend/src/main/resources/application.yaml Base Spring Boot config (application name + active profile)
backend/src/main/resources/application-prod.yaml Production profile config placeholders + actuator/logging settings
backend/src/main/resources/application-dev.yaml Dev profile config (H2, security user, swagger, logging)
backend/src/main/java/org/constructx/policyhub/shared/package-info.java Package-level Javadoc for shared module
backend/src/main/java/org/constructx/policyhub/policies/infrastructure/package-info.java Package-level Javadoc for infrastructure layer
backend/src/main/java/org/constructx/policyhub/policies/domain/package-info.java Package-level Javadoc for domain layer
backend/src/main/java/org/constructx/policyhub/policies/application/PolicyService.java Skeleton service returning example policy list
backend/src/main/java/org/constructx/policyhub/policies/api/dto/PolicyResponse.java DTO for policy API responses
backend/src/main/java/org/constructx/policyhub/policies/api/PolicyController.java REST controller exposing GET /api/v1/policies
backend/src/main/java/org/constructx/policyhub/core/security/SecurityConfig.java Baseline Spring Security filter chain (basic auth + permitted endpoints)
backend/src/main/java/org/constructx/policyhub/core/exception/GlobalExceptionHandler.java Global exception handling returning standardized errors
backend/src/main/java/org/constructx/policyhub/core/exception/ErrorResponse.java Standard error response model
backend/src/main/java/org/constructx/policyhub/config/OpenApiConfig.java OpenAPI metadata configuration
backend/src/main/java/org/constructx/policyhub/config/JacksonConfig.java Jackson configuration via custom ObjectMapper bean
backend/src/main/java/org/constructx/policyhub/PolicyHubApplication.java Spring Boot application entry point
backend/settings.gradle.kts Gradle settings + plugin management repositories
backend/gradlew.bat Gradle wrapper (Windows)
backend/gradlew Gradle wrapper (POSIX)
backend/gradle/wrapper/gradle-wrapper.properties Wrapper distribution configuration
backend/gradle/wrapper/gradle-wrapper.jar Wrapper JAR (binary)
backend/build.gradle.kts Gradle build (plugins, Java 21 toolchain, dependencies)
backend/README.md Developer setup/run documentation
backend/.gitignore Ignore rules for IDE/build artifacts
backend/.gitattributes Line-ending + binary handling rules

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment on lines +25 to +27
maven { url = uri("https://repo.spring.io/snapshot") }
}

Copy link

Copilot AI Mar 27, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The build adds the Spring snapshot repository. This makes dependency/plugin resolution less reproducible and can pull snapshot artifacts unexpectedly. If you don’t require snapshot dependencies, remove this repo (or scope it tightly to the specific artifact/version that needs it).

Suggested change
maven { url = uri("https://repo.spring.io/snapshot") }
}
}

Copilot uses AI. Check for mistakes.
Comment on lines +16 to +18
http
.csrf(csrf -> csrf.disable())
.headers(headers -> headers.frameOptions(frame -> frame.sameOrigin()))
Copy link

Copilot AI Mar 27, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

CSRF is disabled globally. If any browser-accessible or cookie/session-based auth is added later, this creates a real CSRF risk. Consider keeping CSRF enabled by default and only disabling/ignoring it for specific endpoints (e.g., H2 console) or only in the dev profile.

Copilot uses AI. Check for mistakes.
Comment on lines +14 to +18
public ObjectMapper objectMapper() {
return new ObjectMapper()
.registerModule(new JavaTimeModule())
.disable(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS)
.disable(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES);
Copy link

Copilot AI Mar 27, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Defining a brand new ObjectMapper bean replaces Spring Boot’s auto-configured mapper and can drop Boot defaults/modules/customizers (and can also bypass other starters’ Jackson configuration). Prefer customizing the existing mapper via Jackson2ObjectMapperBuilderCustomizer or ObjectMapper customization rather than constructing a new one.

Copilot uses AI. Check for mistakes.
@@ -0,0 +1,7 @@
pluginManagement {
repositories {
maven { url = uri("https://repo.spring.io/snapshot") }
Copy link

Copilot AI Mar 27, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

pluginManagement is configured to use the Spring snapshot repository. If not strictly required, consider removing it to avoid resolving snapshot plugins and to keep builds reproducible.

Suggested change
maven { url = uri("https://repo.spring.io/snapshot") }

Copilot uses AI. Check for mistakes.
gostev-p and others added 2 commits March 27, 2026 14:20
…ationTests.java


remove @activeprofiles("dev") to trigger test on all profiles

Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
…ecurityConfig.java

Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
Copy link
Copy Markdown

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 26 out of 30 changed files in this pull request and generated 4 comments.


💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment on lines +2 to +18
# Uncomment and adjust when the persistence decision is finalized

#spring:
# datasource:
# url: jdbc:postgresql://localhost:5432/policyhub
# driver-class-name: org.postgresql.Driver
# username: ${DB_USERNAME}
# password: ${DB_PASSWORD}
# jpa:
# hibernate:
# ddl-auto: validate
# show-sql: false
# flyway:
# enabled: true
# h2:
# console:
# enabled: false
Copy link

Copilot AI Mar 27, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The prod profile YAML currently comments out all Spring datasource/JPA/Flyway configuration. With spring-boot-starter-data-jpa on the classpath, activating the prod profile will fail to start due to missing datasource properties. Consider either providing env-var based placeholders (url/username/password) or explicitly disabling datasource/JPA autoconfiguration until the persistence setup is ready.

Suggested change
# Uncomment and adjust when the persistence decision is finalized
#spring:
# datasource:
# url: jdbc:postgresql://localhost:5432/policyhub
# driver-class-name: org.postgresql.Driver
# username: ${DB_USERNAME}
# password: ${DB_PASSWORD}
# jpa:
# hibernate:
# ddl-auto: validate
# show-sql: false
# flyway:
# enabled: true
# h2:
# console:
# enabled: false
# Adjust environment variables / values when the persistence decision is finalized
spring:
datasource:
url: ${DB_URL:jdbc:postgresql://localhost:5432/policyhub}
driver-class-name: org.postgresql.Driver
username: ${DB_USERNAME}
password: ${DB_PASSWORD}
jpa:
hibernate:
ddl-auto: validate
show-sql: false
flyway:
enabled: true
h2:
console:
enabled: false

Copilot uses AI. Check for mistakes.
NONSTOP* ) nonstop=true ;;
esac

CLASSPATH="\\\"\\\""
Copy link

Copilot AI Mar 27, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In the Gradle wrapper script, CLASSPATH is set to a literal escaped quote string ("\"\"") instead of pointing at gradle/wrapper/gradle-wrapper.jar. This will prevent ./gradlew from running at all. Set CLASSPATH to the wrapper JAR path as in the standard Gradle-generated script.

Suggested change
CLASSPATH="\\\"\\\""
CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar

Copilot uses AI. Check for mistakes.

<springProfile name="prod">
<appender name="CONSOLE_JSON" class="ch.qos.logback.core.ConsoleAppender">
<encoder class="ch.qos.logback.classic.encoder.JsonEncoder"/>
Copy link

Copilot AI Mar 27, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The prod logging config references ch.qos.logback.classic.encoder.JsonEncoder, which is not provided by logback-classic. As-is, starting with the prod profile will fail during Logback initialization. Either add the appropriate JSON encoder dependency (e.g., logstash-logback-encoder) and use its encoder class, or switch to a built-in encoder/pattern layout.

Suggested change
<encoder class="ch.qos.logback.classic.encoder.JsonEncoder"/>
<encoder class="net.logstash.logback.encoder.LogstashEncoder"/>

Copilot uses AI. Check for mistakes.
Comment on lines +22 to +28
@TestConfiguration
static class TestConfig {
@Bean
public PolicyService policyService() {
return new PolicyService();
}
}
Copy link

Copilot AI Mar 27, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This @WebMvcTest wires a real PolicyService via a @TestConfiguration and then asserts on the exact service output. That makes the controller test brittle (it will fail when PolicyService implementation changes) and mixes controller/unit concerns. Prefer using @MockBean for PolicyService and stubbing the expected response so the test focuses on controller behavior (status/serialization/security).

Copilot uses AI. Check for mistakes.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

feature A new feature request

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants