Skip to content

TEST#1 : Testing location Service with mysql database via Docker connection#3

Open
vikasutf8 wants to merge 36 commits into
test-qafrom
dev-work
Open

TEST#1 : Testing location Service with mysql database via Docker connection#3
vikasutf8 wants to merge 36 commits into
test-qafrom
dev-work

Conversation

@vikasutf8
Copy link
Copy Markdown
Owner

@vikasutf8 vikasutf8 commented Apr 12, 2026

REQ:

  • APi Documentation [README.md or API.md] with respective service
  • Postmant collection public link
  • Confluence or Google Docs link [view mode only]

Summary by Sourcery

Introduce a new Spring Boot-based location-service with MySQL-backed city and airport management APIs, wiring it into the services module and local Docker-based MySQL configuration.

New Features:

  • Add location-service Spring Boot application exposing REST endpoints for managing cities and airports, including search and pagination for cities and city-scoped listing for airports.
  • Introduce shared request/response DTOs, embedded value types, and a generic API response wrapper in common-lib to standardize payloads across services.
  • Provide Docker Compose configuration for a local MySQL 8.0 instance used by the booking/location services.

Enhancements:

  • Update multi-module Maven configuration to include the new location-service module and temporarily disable cloud modules.
  • Document the responsibilities, entities, and planned endpoints for the new location-service in its README, and note MapStruct and Lombok usage in the root README.

@sourcery-ai
Copy link
Copy Markdown

sourcery-ai Bot commented Apr 12, 2026

Reviewer's Guide

Introduces a new Spring Boot-based location-service microservice (cities and airports) wired to MySQL via docker-compose, including domain models, DTOs, mappers, repositories, services, REST controllers, and shared payload/embedded types in common-lib, while disabling unused cloud modules and swapping the services module to location-service.

Sequence diagram for creating an airport (sequence)

sequenceDiagram
  actor Client
  participant AirportController
  participant AirportServiceimpl
  participant CityRepository
  participant AirportRepository
  participant MySQL

  Client->>AirportController: POST /api/v1/airports\nAirportRequest
  AirportController->>AirportServiceimpl: createAirport(request)

  AirportServiceimpl->>CityRepository: findById(request.cityId)
  CityRepository->>MySQL: SELECT city by id
  MySQL-->>CityRepository: City
  CityRepository-->>AirportServiceimpl: City

  AirportServiceimpl->>AirportRepository: existsByIataIgnoreCase(request.iata)
  AirportRepository->>MySQL: SELECT count by iata
  MySQL-->>AirportRepository: exists?
  AirportRepository-->>AirportServiceimpl: boolean

  AirportServiceimpl->>AirportServiceimpl: AirportMapper.toEntity(request)
  AirportServiceimpl->>AirportRepository: save(airport)
  AirportRepository->>MySQL: INSERT airport
  MySQL-->>AirportRepository: persisted Airport
  AirportRepository-->>AirportServiceimpl: Airport

  AirportServiceimpl->>AirportServiceimpl: AirportMapper.toDto(airport)
  AirportServiceimpl-->>AirportController: AirportResponse
  AirportController-->>Client: 201 Created\nApiResponse<AirportResponse>
Loading

ER diagram for City and Airport tables (entity_relationship)

erDiagram
  CITY {
    BIGINT id PK
    VARCHAR name
    VARCHAR country_code
    VARCHAR country
    VARCHAR city_code
    VARCHAR region_code
    VARCHAR time_zone_id
  }

  AIRPORTS {
    BIGINT id PK
    VARCHAR iata
    VARCHAR name
    VARCHAR time_zone_id
    VARCHAR address_street
    VARCHAR address_postal_code
    DOUBLE geo_latitude
    DOUBLE geo_longitude
    BIGINT city_id FK
  }

  CITY ||--o{ AIRPORTS : has
Loading

Class diagram for location-service domain, DTOs, services, and controllers (class)

classDiagram

  %% DOMAIN MODELS
  class City {
    Long id
    String name
    String countryCode
    String country
    String cityCode
    String regionCode
    String timeZoneId
  }

  class Airport {
    Long id
    String iata
    String name
    String timeZone
    Address address
    GeoCode geoCode
    +String getDetailName()
  }

  class Address {
    String street
    String postalCode
  }

  class GeoCode {
    Double latitude
    Double longitude
  }

  City "1" o-- "*" Airport : airports
  Airport "*" --> "1" City : city
  Airport o-- Address
  Airport o-- GeoCode

  %% REQUEST DTOs
  class CityRequest {
    String name
    String countryCode
    String country
    String cityCode
    String regionCode
    String timeZoneOffset
  }

  class AirportRequest {
    String iata
    String name
    String timeZoneId
    Address address
    GeoCode geoCode
    Long cityId
  }

  %% RESPONSE DTOs
  class CityResponse {
    Long id
    String name
    String countryCode
    String country
    String cityCode
    String regionCode
    String timeZoneOffest
  }

  class AirportResponse {
    Long id
    String iata
    String name
    String timeZoneId
    Address address
    GeoCode geoCode
    CityResponse city
  }

  class ApiResponse~T~ {
    boolean success
    String message
    T data
    LocalDateTime timestamp
    +success(data T) ApiResponse~T~
    +success(message String, data T) ApiResponse~T~
  }

  ApiResponse --> CityResponse
  ApiResponse --> AirportResponse

  %% REPOSITORIES
  class CityRepository {
    +Page~City~ findByCountryCodeIgnoreCase(countryCode String, pageable Pageable)
    +boolean existsByCityCodeIgnoreCase(cityCode String)
    +Page~City~ searchByKeyword(keyword String, pageable Pageable)
  }

  class AirportRepository {
    +boolean existsByIataIgnoreCase(iata String)
    +boolean existsByIataIgnoreCaseAndIdNot(iata String, id Long)
    +List~Airport~ findByCityId(cityId Long)
    +boolean existsByCityId(cityId Long)
  }

  CityRepository ..|> JpaRepository
  AirportRepository ..|> JpaRepository

  %% SERVICES
  class CityService {
    +CityResponse createCity(cityRequest CityRequest)
    +CityResponse updateCity(id Long, cityRequest CityRequest)
    +CityResponse getCityById(id Long)
    +void deleteCity(id Long)
    +Page~CityResponse~ getAllCities(pageable Pageable)
    +Page~CityResponse~ searchCities(keyword String, pageable Pageable)
    +Page~CityResponse~ getCitiesByCountryCode(countryCode String, pageable Pageable)
    +boolean cityExists(cityCode String)
  }

  class CityServiceImpl {
    -CityRepository cityRepository
    +CityResponse createCity(cityRequest CityRequest)
    +CityResponse updateCity(id Long, cityRequest CityRequest)
    +CityResponse getCityById(id Long)
    +void deleteCity(id Long)
    +Page~CityResponse~ getAllCities(pageable Pageable)
    +Page~CityResponse~ searchCities(keyword String, pageable Pageable)
    +Page~CityResponse~ getCitiesByCountryCode(countryCode String, pageable Pageable)
    +boolean cityExists(cityCode String)
  }

  CityServiceImpl ..|> CityService
  CityServiceImpl --> CityRepository

  class AirportService {
    +AirportResponse createAirport(request AirportRequest)
    +AirportResponse updateAirport(id Long, request AirportRequest)
    +List~AirportResponse~ getAllAirports()
    +AirportResponse getAirportById(id Long)
    +void deleteAirport(id Long)
    +List~AirportResponse~ getAirportsByCityId(cityId Long)
  }

  class AirportServiceimpl {
    -AirportRepository airportRepository
    -CityRepository cityRepository
    -CityService cityService
    +AirportResponse createAirport(request AirportRequest)
    +AirportResponse updateAirport(id Long, request AirportRequest)
    +List~AirportResponse~ getAllAirports()
    +AirportResponse getAirportById(id Long)
    +void deleteAirport(id Long)
    +List~AirportResponse~ getAirportsByCityId(cityId Long)
  }

  AirportServiceimpl ..|> AirportService
  AirportServiceimpl --> AirportRepository
  AirportServiceimpl --> CityRepository
  AirportServiceimpl --> CityService

  %% MAPPERS
  class CityMapper {
    +City toEntity(request CityRequest)
    +CityResponse toDto(city City)
    +void updateEntityFromRequest(request CityRequest, city City)
  }

  class AirportMapper {
    -CityMapper cityMapper
    +Airport toEntity(request AirportRequest)
    +AirportResponse toDto(airport Airport)
    +void updateEntityFromRequest(request AirportRequest, airport Airport)
  }

  CityMapper --> City
  CityMapper --> CityRequest
  CityMapper --> CityResponse

  AirportMapper --> Airport
  AirportMapper --> AirportRequest
  AirportMapper --> AirportResponse
  AirportMapper --> CityMapper

  %% CONTROLLERS
  class CityController {
    -CityService cityService
    +ResponseEntity~ApiResponse~ createCity(cityRequest CityRequest)
    +ResponseEntity~ApiResponse~ updateCity(id Long, cityRequest CityRequest)
    +ResponseEntity~ApiResponse~ getCityById(id Long)
    +ResponseEntity~Void~ deleteCity(id Long)
    +ResponseEntity~ApiResponse~ getAllCities(pageable Pageable)
    +ResponseEntity~ApiResponse~ searchCities(keyword String, pageable Pageable)
    +ResponseEntity~ApiResponse~ getCitiesByCountryCode(countryCode String, pageable Pageable)
    +ResponseEntity~ApiResponse~ cityExists(cityCode String)
  }

  class AirportController {
    -AirportService airportService
    +ResponseEntity~ApiResponse~ createAirport(request AirportRequest)
    +ResponseEntity~ApiResponse~ updateAirport(id Long, request AirportRequest)
    +ResponseEntity~ApiResponse~ getAirportById(id Long)
    +ResponseEntity~ApiResponse~ getAllAirports()
    +ResponseEntity~Void~ deleteAirport(id Long)
    +ResponseEntity~ApiResponse~ getAirportsByCityId(cityId Long)
  }

  class HomeController {
    +String HomeController()
  }

  CityController --> CityService
  AirportController --> AirportService
Loading

File-Level Changes

Change Details Files
Add a new location-service Spring Boot microservice for managing cities and airports, including REST controllers, services, repositories, and data models.
  • Create City and Airport JPA entities with relationships, validation-constrained embedded Address and GeoCode value objects, and a bidirectional City–Airport association.
  • Introduce CityService/AirportService interfaces with implementations handling CRUD operations, uniqueness checks (city codes, IATA codes), and lookup/search APIs with pagination where applicable.
  • Expose HTTP endpoints for cities and airports via CityController and AirportController using ApiResponse wrapper, validation on request DTOs, and pageable-based queries.
services/location-service/src/main/java/com/flynest/location_service/model/City.java
services/location-service/src/main/java/com/flynest/location_service/model/Airport.java
common-lib/src/main/java/com/flynest/emabbedable/Address.java
common-lib/src/main/java/com/flynest/emabbedable/GeoCode.java
services/location-service/src/main/java/com/flynest/location_service/service/CityService.java
services/location-service/src/main/java/com/flynest/location_service/service/impl/CityServiceImpl.java
services/location-service/src/main/java/com/flynest/location_service/service/AirportService.java
services/location-service/src/main/java/com/flynest/location_service/service/impl/AirportServiceimpl.java
services/location-service/src/main/java/com/flynest/location_service/controller/CityController.java
services/location-service/src/main/java/com/flynest/location_service/controller/AirportController.java
services/location-service/src/main/java/com/flynest/location_service/controller/HomeController.java
Introduce mapping, request, and response DTO infrastructure in common-lib and location-service for decoupled API contracts.
  • Add CityRequest, AirportRequest DTOs with bean validation annotations and associated CityResponse, AirportResponse DTOs for outbound payloads.
  • Implement CityMapper and AirportMapper components to convert between entities and DTOs, supporting partial updates via null-check-based field mapping.
  • Add a generic ApiResponse wrapper to standardize REST responses with success flag, message, data, and timestamp.
services/location-service/src/main/java/com/flynest/location_service/mapper/CityMapper.java
services/location-service/src/main/java/com/flynest/location_service/mapper/AirportMapper.java
common-lib/src/main/java/com/flynest/payload/request/CityRequest.java
common-lib/src/main/java/com/flynest/payload/request/AirportRequest.java
common-lib/src/main/java/com/flynest/payload/response/CityResponse.java
common-lib/src/main/java/com/flynest/payload/response/AirportResponse.java
common-lib/src/main/java/com/flynest/payload/response/ApiResponse.java
Configure the new location-service Maven module and project wiring, and disable unrelated modules.
  • Add services/location-service/pom.xml with Spring Boot, JPA, WebMVC, MySQL, validation, and Lombok dependencies plus compiler plugin configuration for Lombok annotation processing.
  • Introduce Maven Wrapper scripts and properties for the location-service, and a minimal CommonLibApplication class to make common-lib a valid Java module.
  • Adjust parent POMs so services includes location-service instead of user-services and comment out cloud modules (service-registry, config-server, api-gateway).
services/location-service/pom.xml
services/location-service/mvnw
services/location-service/mvnw.cmd
services/location-service/.mvn/wrapper/maven-wrapper.properties
services/pom.xml
cloud/pom.xml
common-lib/src/main/java/com.flynest/CommonLibApplication.java
Add configuration, documentation, and infrastructure to run location-service with a MySQL database via Docker.
  • Provide application.yaml configuring location-service on port 9091 with a MySQL datasource pointing at a local saas-booking schema and pos-booking user.
  • Add a docker-compose.yaml defining a MySQL 8.0 service (booking-mysql-db) with credentials and a named volume for persistence, plus a healthcheck.
  • Document the location-service responsibilities, domain model, caching/bulk operation ideas, and REST endpoints in services/location-service/readme.md, and extend root README with MapStruct/Lombok notes.
services/location-service/src/main/resources/application.yaml
docker-compose.yaml
services/location-service/readme.md
README.md

Tips and commands

Interacting with Sourcery

  • Trigger a new review: Comment @sourcery-ai review on the pull request.
  • Continue discussions: Reply directly to Sourcery's review comments.
  • Generate a GitHub issue from a review comment: Ask Sourcery to create an
    issue from a review comment by replying to it. You can also reply to a
    review comment with @sourcery-ai issue to create an issue from it.
  • Generate a pull request title: Write @sourcery-ai anywhere in the pull
    request title to generate a title at any time. You can also comment
    @sourcery-ai title on the pull request to (re-)generate the title at any time.
  • Generate a pull request summary: Write @sourcery-ai summary anywhere in
    the pull request body to generate a PR summary at any time exactly where you
    want it. You can also comment @sourcery-ai summary on the pull request to
    (re-)generate the summary at any time.
  • Generate reviewer's guide: Comment @sourcery-ai guide on the pull
    request to (re-)generate the reviewer's guide at any time.
  • Resolve all Sourcery comments: Comment @sourcery-ai resolve on the
    pull request to resolve all Sourcery comments. Useful if you've already
    addressed all the comments and don't want to see them anymore.
  • Dismiss all Sourcery reviews: Comment @sourcery-ai dismiss on the pull
    request to dismiss all existing Sourcery reviews. Especially useful if you
    want to start fresh with a new review - don't forget to comment
    @sourcery-ai review to trigger a new review!

Customizing Your Experience

Access your dashboard to:

  • Enable or disable review features such as the Sourcery-generated pull request
    summary, the reviewer's guide, and others.
  • Change the review language.
  • Add, remove or edit custom review instructions.
  • Adjust other review settings.

Getting Help

Copy link
Copy Markdown

@sourcery-ai sourcery-ai Bot left a comment

Choose a reason for hiding this comment

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

Hey - I've found 2 issues, and left some high level feedback:

  • The AirportMapper and CityMapper classes mix static methods with an injected dependency (CityMapper in AirportMapper), which is both unused and inconsistent with their static API; either make these mappers fully static utility classes (no Spring component/dependency) or fully instance-based beans without static methods.
  • The service implementation class AirportServiceimpl is mis-capitalized and lives in a Repository package with a capital "R" in imports (com.flynest.location_service.Repository), which is inconsistent with Java/Spring naming conventions and may cause confusion; consider renaming to AirportServiceImpl and normalizing package names to lowercase (e.g. repository).
  • This PR includes IDE and build artifacts (e.g. .idea/*, common-lib/target/...); these should generally be excluded via .gitignore and removed from the repository to keep the VCS clean.
Prompt for AI Agents
Please address the comments from this code review:

## Overall Comments
- The `AirportMapper` and `CityMapper` classes mix static methods with an injected dependency (`CityMapper` in `AirportMapper`), which is both unused and inconsistent with their static API; either make these mappers fully static utility classes (no Spring component/dependency) or fully instance-based beans without static methods.
- The service implementation class `AirportServiceimpl` is mis-capitalized and lives in a `Repository` package with a capital "R" in imports (`com.flynest.location_service.Repository`), which is inconsistent with Java/Spring naming conventions and may cause confusion; consider renaming to `AirportServiceImpl` and normalizing package names to lowercase (e.g. `repository`).
- This PR includes IDE and build artifacts (e.g. `.idea/*`, `common-lib/target/...`); these should generally be excluded via `.gitignore` and removed from the repository to keep the VCS clean.

## Individual Comments

### Comment 1
<location path="services/location-service/src/main/java/com/flynest/location_service/model/Airport.java" line_range="39-44" />
<code_context>
+    private com.flynest.emabbedable.GeoCode geoCode;
+
+    @ManyToOne(fetch = FetchType.LAZY)
+    @JsonIgnore
+    @JoinColumn(name = "city_id", nullable = false)
+    private City city;
+
+    @JsonIgnore
+    @Transient
+    public String getDetailName(){
+        if(city != null && city.getCityCode() != null){
</code_context>
<issue_to_address>
**issue (bug_risk):** Use the JPA @Transient annotation instead of java.beans.Transient for getDetailName().

`java.beans.Transient` is only used by the JavaBeans introspector and is ignored by JPA. Replace it with `jakarta.persistence.Transient` so `getDetailName()` is treated as a non-persistent computed property. Keep `@JsonIgnore` if you also want it excluded from JSON serialization.
</issue_to_address>

### Comment 2
<location path="services/location-service/readme.md" line_range="43-47" />
<code_context>
+- cache ttl
+
+
+### Bulk Operations
+- Importing all airport of India
+  - POST: api/airports/bulk
+  - POST: api/cities/bulk
+- Validation failure
+
+### Dto & Mappeer Pattern
</code_context>
<issue_to_address>
**nitpick (typo):** Correct pluralization in the bulk operations description.

"Importing all airport of India" should be updated to "Importing all airports of India" or "Importing all airports in India" for more natural phrasing.

```suggestion
### Bulk Operations
- Importing all airports in India
  - POST: api/airports/bulk
  - POST: api/cities/bulk
- Validation failure
```
</issue_to_address>

Sourcery is free for open source - if you like our reviews please consider sharing them ✨
Help me be more useful! Please click 👍 or 👎 on each comment and I'll use the feedback to improve your reviews.

Comment on lines +39 to +44
@JsonIgnore
@JoinColumn(name = "city_id", nullable = false)
private City city;

@JsonIgnore
@Transient
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

issue (bug_risk): Use the JPA @transient annotation instead of java.beans.Transient for getDetailName().

java.beans.Transient is only used by the JavaBeans introspector and is ignored by JPA. Replace it with jakarta.persistence.Transient so getDetailName() is treated as a non-persistent computed property. Keep @JsonIgnore if you also want it excluded from JSON serialization.

Comment on lines +43 to +47
### Bulk Operations
- Importing all airport of India
- POST: api/airports/bulk
- POST: api/cities/bulk
- Validation failure
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

nitpick (typo): Correct pluralization in the bulk operations description.

"Importing all airport of India" should be updated to "Importing all airports of India" or "Importing all airports in India" for more natural phrasing.

Suggested change
### Bulk Operations
- Importing all airport of India
- POST: api/airports/bulk
- POST: api/cities/bulk
- Validation failure
### Bulk Operations
- Importing all airports in India
- POST: api/airports/bulk
- POST: api/cities/bulk
- Validation failure

TEST#2 : UserServuice with Authentication and authorization
…and mapper layers; add application configuration and Maven wrapper
Feat: Airline and AirCraft Services
…nfiguration, Maven wrapper, and essential files
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant