Develop#17
Merged
Merged
Conversation
…ations and enhance OTP functionality
There was a problem hiding this comment.
Pull request overview
This PR expands the identity and bundle modules by adding new REST endpoints and shifting several controller/service interactions toward async (CompletableFuture) execution, while also updating bundle persistence mappings and adding basic OpenAPI metadata.
Changes:
- Added a new Bundle API (
BundleController) plus new bundle commands/handlers and DTOs, and wired bundle module component scanning. - Updated identity controllers to return async responses (and added a custom OTP send endpoint).
- Adjusted bundle JPA entity relationships (adding back-references) and introduced
BaseApplicationService.currentUsername().
Reviewed changes
Copilot reviewed 21 out of 21 changed files in this pull request and generated 25 comments.
Show a summary per file
| File | Description |
|---|---|
| identity/src/main/java/io/theurl/identity/interfaces/controller/OnetimePasswordController.java | Adds OTP endpoint and extensive Javadoc for OTP flows. |
| identity/src/main/java/io/theurl/identity/interfaces/controller/AuthController.java | Switches token endpoints to return CompletableFuture instead of blocking .join(). |
| identity/src/main/java/io/theurl/identity/interfaces/controller/AccountController.java | Changes several mutation endpoints to return 204 No Content. |
| framework/src/main/java/io/theurl/framework/application/BaseApplicationService.java | Adds currentUsername() helper alongside currentUserId(). |
| bundle/src/main/java/io/theurl/bundle/persistence/profile/BundleMapProfile.java | Modifies ModelMapper mapping logic for Bundle entity ↔ domain. |
| bundle/src/main/java/io/theurl/bundle/persistence/entity/BundleItem.java | Adds JPA ManyToOne back-reference to Bundle. |
| bundle/src/main/java/io/theurl/bundle/persistence/entity/BundleExtend.java | Collapses imports and adds JPA OneToOne back-reference to Bundle. |
| bundle/src/main/java/io/theurl/bundle/persistence/entity/BundleComment.java | Collapses imports and adds JPA ManyToOne back-reference to Bundle. |
| bundle/src/main/java/io/theurl/bundle/persistence/entity/Bundle.java | Removes @JoinColumn usage from relationships and relies on mappedBy. |
| bundle/src/main/java/io/theurl/bundle/interfaces/controller/package-info.java | Adds package-level OpenAPI definition metadata. |
| bundle/src/main/java/io/theurl/bundle/interfaces/controller/BundleController.java | Introduces new Bundle REST API endpoints (create/update/delete/item ops). |
| bundle/src/main/java/io/theurl/bundle/BundleApplication.java | Adds component scanning for framework + bundle packages. |
| bundle/src/main/java/io/theurl/bundle/application/implement/BundleApplicationServiceImpl.java | Implements create/update/delete via mediator; stubs item operations. |
| bundle/src/main/java/io/theurl/bundle/application/handler/BundleUpdateCommandHandler.java | New handler for updating bundles. |
| bundle/src/main/java/io/theurl/bundle/application/handler/BundleDeleteCommandHandler.java | New handler for deleting bundles with ownership checks. |
| bundle/src/main/java/io/theurl/bundle/application/handler/BundleCreateCommandHandler.java | Updates create handler behavior and publishes completion events. |
| bundle/src/main/java/io/theurl/bundle/application/dto/BundleItemEditDto.java | New DTO for bundle item edit operations. |
| bundle/src/main/java/io/theurl/bundle/application/dto/BundleCreateDto.java | Adds shared flag for bundle creation. |
| bundle/src/main/java/io/theurl/bundle/application/contract/BundleApplicationService.java | Extends contract with item append/update/remove methods. |
| bundle/src/main/java/io/theurl/bundle/application/command/BundleUpdateCommand.java | New command for updating bundle metadata. |
| bundle/src/main/java/io/theurl/bundle/application/command/BundleDeleteCommand.java | New command for deleting bundles. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
Comment on lines
+18
to
+26
| /** | ||
| * Send a one-time password (OTP) to the specified recipient for authentication purposes. | ||
| * This endpoint allows clients to request the sending of a one-time password (OTP) to a specified recipient, which can be used for authentication purposes. | ||
| * The client must provide the recipient's information in the request body, and the server will process the request to generate and send the OTP to the recipient. | ||
| * The server will return a response indicating the success or failure of the OTP sending operation, along with any relevant information such as the OTP code or an error message if the operation fails. | ||
| * | ||
| * @param request The request containing the recipient's information. | ||
| * @return A CompletableFuture representing the asynchronous operation, containing the OTP code or an error message. | ||
| */ |
Comment on lines
+32
to
+40
| /** | ||
| * Send a one-time password (OTP) to the specified recipient for email change verification. | ||
| * This endpoint allows clients to request the sending of a one-time password (OTP) to a specified recipient for the purpose of verifying an email change request. | ||
| * The client must provide the recipient's information in the request body, and the server will process the request to generate and send the OTP to the recipient for email change verification. | ||
| * The server will return a response indicating the success or failure of the OTP sending operation, along with any relevant information such as the OTP code or an error message if the operation fails. | ||
| * | ||
| * @param request The request containing the recipient's information. | ||
| * @return A CompletableFuture representing the asynchronous operation, containing the OTP code or an error message. | ||
| */ |
Comment on lines
+46
to
+54
| /** | ||
| * Send a one-time password (OTP) to the specified recipient for password reset verification. | ||
| * This endpoint allows clients to request the sending of a one-time password (OTP) to a specified recipient for the purpose of verifying a password reset request. | ||
| * The client must provide the recipient's information in the request body, and the server will process the request to generate and send the OTP to the recipient for password reset verification. | ||
| * The server will return a response indicating the success or failure of the OTP sending operation, along with any relevant information such as the OTP code or an error message if the operation fails. | ||
| * | ||
| * @param request The request containing the recipient's information. | ||
| * @return A CompletableFuture representing the asynchronous operation, containing the OTP code or an error message. | ||
| */ |
Comment on lines
+60
to
+69
| /** | ||
| * Send a one-time password (OTP) to the specified recipient for a custom intent. | ||
| * This endpoint allows clients to request the sending of a one-time password (OTP) to a specified recipient for a custom intent defined by the client. | ||
| * The client must provide the recipient's information in the request body and specify the intent as a query parameter, and the server will process the request to generate and send the OTP to the recipient for the specified intent. | ||
| * The server will return a response indicating the success or failure of the OTP sending operation, along with any relevant information such as the OTP code or an error message if the operation fails. | ||
| * | ||
| * @param request The request containing the recipient's information. | ||
| * @param intent The intent for which the OTP is being sent. | ||
| * @return A CompletableFuture representing the asynchronous operation, containing the OTP code or an error message. | ||
| */ |
Comment on lines
+124
to
137
| @Override | ||
| public CompletableFuture<Void> appendItemAsync(String vanity, BundleItemEditDto data) { | ||
| return null; | ||
| } | ||
|
|
||
| @Override | ||
| public CompletableFuture<Void> updateItemAsync(String vanity, long itemId, BundleItemEditDto data) { | ||
| return null; | ||
| } | ||
|
|
||
| @Override | ||
| public CompletableFuture<Void> removeItemAsync(String vanity, long itemId) { | ||
| return null; | ||
| } |
Comment on lines
+60
to
+69
| /** | ||
| * Send a one-time password (OTP) to the specified recipient for a custom intent. | ||
| * This endpoint allows clients to request the sending of a one-time password (OTP) to a specified recipient for a custom intent defined by the client. | ||
| * The client must provide the recipient's information in the request body and specify the intent as a query parameter, and the server will process the request to generate and send the OTP to the recipient for the specified intent. | ||
| * The server will return a response indicating the success or failure of the OTP sending operation, along with any relevant information such as the OTP code or an error message if the operation fails. | ||
| * | ||
| * @param request The request containing the recipient's information. | ||
| * @param intent The intent for which the OTP is being sent. | ||
| * @return A CompletableFuture representing the asynchronous operation, containing the OTP code or an error message. | ||
| */ |
Comment on lines
38
to
42
| } | ||
| aggregate.setOwner(message.getOwnerId(), message.getOwnerName()); | ||
| repository.save(aggregate, userId); | ||
| context.onComplete(List.copyOf(aggregate.getEvents())); | ||
| return CompletableFuture.completedFuture(null); |
Comment on lines
+36
to
+46
| var userId = Long.getLong(Objects.requireNonNull(getRequest()).getUserPrincipal().getName()); | ||
|
|
||
| if (aggregate.getOwnerId() > 0) { | ||
| if (!Objects.equals(aggregate.getOwnerId(), userId)) { | ||
| throw new UnauthorizedAccessException("You are not the owner of this bundle"); | ||
| } | ||
| } else { | ||
| if (!getRequest().isUserInRole("ADMIN")) { | ||
| throw new UnauthorizedAccessException("You are not the owner of this bundle"); | ||
| } | ||
| } |
Comment on lines
+29
to
+42
| public CompletableFuture<Void> handleAsync(BundleUpdateCommand message, MessageContext context) { | ||
| var aggregate = repository.findByVanity(message.getVanity()); | ||
|
|
||
| if (aggregate == null) { | ||
| throw new EntityNotFoundException("Bundle with vanity '" + message.getVanity() + "' not found."); | ||
| } | ||
|
|
||
| aggregate.setName(message.getName()); | ||
| aggregate.setDescription(message.getDescription()); | ||
| aggregate.setImage(message.getImage()); | ||
|
|
||
| repository.save(aggregate, getUserId()); | ||
|
|
||
| return CompletableFuture.completedFuture(null); |
Comment on lines
+32
to
+34
| @OneToOne(fetch = FetchType.LAZY) | ||
| @JoinColumn(name = "id") | ||
| private Bundle bundle; |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
No description provided.