Skip to content

Commit

Permalink
feat(be:FSADT1-1575): Create read-only Client Summary (BE) (#1331)
Browse files Browse the repository at this point in the history
* feat(be:FSADT1-1575): First draft

* no message

* Added missing field in dto

* Added missing field in dto

* feat(be:feat/be/FSADT1-1575): Populated good standing indicator

* Added descriptions

* no message

* feat(be:FSADT1-1575): Passed groups to legacy

* feat(be:FSADT1-1575): Passed groups to legacy

* Updated query

* Added missing dto

* Removed unneeded field

* Added new field as per requested

* feat(be:FSADT1-1575): Changes done after code review

* Added javadoc

* Added test

* Fixed test

* Improved test

* feat(be:FSADT1-1575): Added more tests

* Fixed test

* feat(be:FSADT1-1575): Added more tests

* Added javadoc

* Made code reviews

* Added more javadocs

* Made more code reviews

* Made changes after code reviews

* SonaCloud fixes

* SonarCloud fixes

* Added more tests

* chore: simplifying boolean check

---------

Co-authored-by: Paulo Gomes da Cruz Junior <[email protected]>
  • Loading branch information
mamartinezmejia and paulushcgcj authored Dec 5, 2024
1 parent f96b918 commit eeb04d4
Show file tree
Hide file tree
Showing 23 changed files with 878 additions and 119 deletions.
2 changes: 1 addition & 1 deletion .github/workflows/pr-open.yml
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ jobs:
matrix:
package: [backend, database, frontend, legacy, legacydb, processor]
steps:
- uses: bcgov-nr/action-builder-ghcr@v2.3.0
- uses: bcgov-nr/action-builder-ghcr@v2.2.0
name: Build (${{ matrix.package }})
with:
package: ${{ matrix.package }}
Expand Down
5 changes: 3 additions & 2 deletions backend/Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,6 @@ RUN mvn versions:set -DnewVersion=${APP_VERSION} -f pom.xml -DskipTests -Dtests.
# Build
RUN mvn -Pnative native:compile


### Deployer
FROM gcr.io/distroless/java-base:nonroot AS deploy
ARG PORT=8080
Expand All @@ -44,5 +43,7 @@ USER 1001
EXPOSE ${PORT}
HEALTHCHECK CMD curl -f http://localhost:${PORT}/actuator/health | grep '"status":"UP"'

ENV SPRING_PROFILES_ACTIVE=container

# Startup
ENTRYPOINT ["/app/nr-forest-client-backend","--spring.profiles.active=container"]
ENTRYPOINT ["/app/nr-forest-client-backend"]
Original file line number Diff line number Diff line change
Expand Up @@ -4,14 +4,15 @@
import ca.bc.gov.app.dto.bcregistry.ClientDetailsDto;
import ca.bc.gov.app.dto.client.ClientListDto;
import ca.bc.gov.app.dto.client.ClientLookUpDto;
import ca.bc.gov.app.dto.legacy.ForestClientDetailsDto;
import ca.bc.gov.app.exception.NoClientDataFound;
import ca.bc.gov.app.service.client.ClientLegacyService;
import ca.bc.gov.app.service.client.ClientService;
import ca.bc.gov.app.util.JwtPrincipalUtil;
import io.micrometer.observation.annotation.Observed;
import java.util.List;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import java.util.List;
import org.apache.commons.text.WordUtils;
import org.springframework.data.util.Pair;
import org.springframework.http.MediaType;
Expand All @@ -35,8 +36,19 @@ public class ClientController {
private final ClientService clientService;
private final ClientLegacyService clientLegacyService;

/**
* Retrieves the details of a client based on the provided incorporation number.
*
* <p>This endpoint is used to fetch client details by their incorporation number. The request is
* authenticated using a JWT, and additional information (such as user ID, business ID, and
* provider) is extracted from the token to authorize the request.
*
* @param clientNumber the incorporation number of the client whose details are being requested
* @param principal the JWT authentication token containing user and business information
* @return a {@link Mono} emitting the {@link ClientDetailsDto} containing the client's details
*/
@GetMapping("/{clientNumber}")
public Mono<ClientDetailsDto> getClientDetails(
public Mono<ClientDetailsDto> getClientDetailsByIncorporationNumber(
@PathVariable String clientNumber,
JwtAuthenticationToken principal
) {
Expand All @@ -45,48 +57,83 @@ public Mono<ClientDetailsDto> getClientDetails(
JwtPrincipalUtil.getUserId(principal)
);
return clientService
.getClientDetails(
.getClientDetailsByIncorporationNumber(
clientNumber,
JwtPrincipalUtil.getUserId(principal),
JwtPrincipalUtil.getBusinessId(principal),
JwtPrincipalUtil.getProvider(principal)
);
}

/**
* Handles HTTP GET requests to retrieve client details based on the provided client number.
*
* <p>This method fetches the details of a client from the {@code ClientService} using the
* specified {@code clientNumber}. The caller's JWT authentication token is used to extract
* user-related information such as groups and user ID.</p>
*
* @param clientNumber the unique identifier of the client whose details are to be retrieved.
* @param principal the {@link JwtAuthenticationToken} containing the authenticated user's
* information, including their roles and groups.
* @return a {@link Mono} emitting the {@link ForestClientDetailsDto} containing the requested
* client details, or an error if the client cannot be found or accessed.
*/
@GetMapping("/details/{clientNumber}")
public Mono<ForestClientDetailsDto> getClientDetailsByClientNumber(
@PathVariable String clientNumber,
JwtAuthenticationToken principal
) {
log.info("Requesting client details for client number {} from the client service. {}",
clientNumber,
JwtPrincipalUtil.getUserId(principal)
);
return clientService.getClientDetailsByClientNumber(
clientNumber,
JwtPrincipalUtil.getGroups(principal));
}

/**
* Performs a full-text search for clients based on the provided keyword, with pagination support.
*
* <p>This endpoint allows searching for clients by a keyword. The results are paginated, and the
* total count of matching records is included in the response headers.
*
* @param page the page number to retrieve (default is 0)
* @param size the number of records per page (default is 10)
* @param keyword the keyword to search for (default is an empty string, which returns all
* records)
* @param serverResponse the HTTP response to include the total count of records in the headers
* @return a {@link Flux} emitting {@link ClientListDto} objects containing the search results
*/
@GetMapping("/search")
public Flux<ClientListDto> fullSearch(
@RequestParam(required = false, defaultValue = "0") int page,
@RequestParam(required = false, defaultValue = "10") int size,
@RequestParam(required = false, defaultValue = "") String keyword,
ServerHttpResponse serverResponse) {
ServerHttpResponse serverResponse
) {
log.info("Listing clients: page={}, size={}, keyword={}", page, size, keyword);

return clientLegacyService
.search(
page,
size,
keyword
)
.search(page, size, keyword)
.doOnNext(pair -> {
Long count = pair.getSecond();

serverResponse
.getHeaders()
.putIfAbsent(
ApplicationConstant.X_TOTAL_COUNT,
List.of(count.toString())
);
}
)
.getHeaders()
.putIfAbsent(
ApplicationConstant.X_TOTAL_COUNT,
List.of(count.toString())
);
})
.map(Pair::getFirst)
.doFinally(signalType ->
.doFinally(signalType ->
serverResponse
.getHeaders()
.putIfAbsent(
ApplicationConstant.X_TOTAL_COUNT,
List.of("0")
)
.getHeaders()
.putIfAbsent(
ApplicationConstant.X_TOTAL_COUNT,
List.of("0")
)
);
}

Expand All @@ -104,24 +151,45 @@ public Flux<ClientLookUpDto> findByClientName(@PathVariable String name) {
.map(client -> client.withName(WordUtils.capitalize(client.name())));
}

/**
* Finds a client based on their registration number.
*
* <p>This endpoint retrieves client information by searching for a registration number.
* If no client is found, an error is returned.
*
* @param registrationNumber the registration number of the client to look up
* @return a {@link Mono} emitting the {@link ClientLookUpDto} if found, or an error
* if no data exists
*/
@GetMapping(value = "/incorporation/{registrationNumber}")
public Mono<ClientLookUpDto> findByRegistrationNumber(
@PathVariable String registrationNumber) {
log.info("Requesting a client with registration number {} from the client service.",
registrationNumber);
registrationNumber);
return clientService
.findByClientNameOrIncorporation(registrationNumber)
.next()
.switchIfEmpty(Mono.error(new NoClientDataFound(registrationNumber)));
}

/**
* Searches for an individual client by user ID and last name.
*
* <p>This endpoint fetches an individual client using their user ID and last name.
* The request is validated against existing records in the system.
*
* @param userId the unique identifier of the individual to search for
* @param lastName the last name of the individual to search for
* @return a {@link Mono} indicating completion, or an error if the individual is not found
*/
@GetMapping(value = "/individual/{userId}")
public Mono<Void> findByIndividual(
@PathVariable String userId,
@RequestParam String lastName
) {
log.info("Receiving request to search individual with id {} and last name {}", userId,
lastName);
log.info("Receiving request to search individual with id {} and last name {}",
userId,
lastName);
return clientService.findByIndividual(userId, lastName);
}

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
package ca.bc.gov.app.dto.legacy;

public record ForestClientContactDto(
String clientNumber,
String clientLocnCode,
String contactCode,
String contactName,
String businessPhone,
String secondaryPhone,
String faxNumber,
String emailAddress,
String createdBy,
String updatedBy,
Long orgUnit
) {

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
package ca.bc.gov.app.dto.legacy;

import java.time.LocalDate;
import java.util.List;
import lombok.With;

@With
public record ForestClientDetailsDto(
String clientNumber,
String clientName,
String legalFirstName,
String legalMiddleName,
String clientStatusCode,
String clientStatusDesc,
String clientTypeCode,
String clientTypeDesc,
String clientIdTypeCode,
String clientIdTypeDesc,
String clientIdentification,
String registryCompanyTypeCode,
String corpRegnNmbr,
String clientAcronym,
String wcbFirmNumber,
String clientComment,
LocalDate clientCommentUpdateDate,
String clientCommentUpdateUser,
String goodStandingInd,
LocalDate birthdate,

List<ForestClientLocationDto> addresses,
List<ForestClientContactDto> contacts,
List<ForestClientDoingBusinessAsDto> doingBusinessAs
) {

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
package ca.bc.gov.app.dto.legacy;

import lombok.With;

@With
public record ForestClientDoingBusinessAsDto(
String clientNumber,
String doingBusinessAsName,
String createdBy,
String updatedBy,
Long orgUnit
) {

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
package ca.bc.gov.app.dto.legacy;

import java.time.LocalDate;
import lombok.With;

@With
public record ForestClientLocationDto(
String clientNumber,
String clientLocnCode,
String clientLocnName,
String addressOne,
String addressTwo,
String addressThree,
String city,
String province,
String postalCode,
String country,
String businessPhone,
String homePhone,
String cellPhone,
String faxNumber,
String emailAddress,
String locnExpiredInd,
LocalDate returnedMailDate,
String trustLocationInd,
String cliLocnComment,
String createdBy,
String updatedBy,
Long orgUnit
) {

}

Loading

0 comments on commit eeb04d4

Please sign in to comment.