Midas Lab
Midas Lab
Midas Lab
Overview:
This document details the Backend Engineer Code Assessment, designed to evaluate
your skills in integrating Stripe payment processing into a pre-existing Spring Boot
application leveraging Temporal Workflow Engine.
Project Setup:
Tasks:
AccountController Code:
package com.midas.app.controllers;
import com.midas.app.mappers.Mapper;
import com.midas.app.models.Account;
import com.midas.app.models.User.ProviderType;
import com.midas.app.services.AccountService;
import com.midas.generated.api.AccountsApi;
import com.midas.generated.model.AccountDto;
import com.midas.generated.model.CreateAccountDto;
import io.temporal.client.WorkflowClient;
import io.temporal.client.WorkflowOptions;
import java.util.List;
import lombok.RequiredArgsConstructor;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.*;
@Controller
@RequestMapping("/api/accounts")
@RequiredArgsConstructor
public class AccountController implements AccountsApi {
@Override
@PostMapping("/signup")
public ResponseEntity<AccountDto> createUserAccount(
@RequestBody CreateAccountDto createAccountDto) {
logger.info("Creating account for user with email: {}",
createAccountDto.getEmail());
WorkflowOptions options =
WorkflowOptions.newBuilder().setTaskQueue("user-signup-
tasks").build();
UserSignupWorkflow workflow =
workflowClient.newWorkflowStub(UserSignupWorkflow.class, options);
@Override
@GetMapping
public ResponseEntity<List<AccountDto>> getUserAccounts() {
logger.info("Retrieving all accounts");
User/Accounts information:
package com.midas.app.models;
import jakarta.persistence.*;
import java.time.OffsetDateTime;
import java.util.UUID;
import lombok.*;
import org.hibernate.annotations.CreationTimestamp;
import org.hibernate.annotations.UpdateTimestamp;
@Setter
@Getter
@RequiredArgsConstructor
@AllArgsConstructor
@Builder
@Entity
@Table(name = "accounts")
public class Account {
@Id
@Column(name = "id")
@GeneratedValue
private UUID id;
@Column(name = "first_name")
private String firstName;
@Column(name = "last_name")
private String lastName;
@Column(name = "email")
private String email;
@Enumerated(EnumType.STRING)
@Column(name = "provider_type")
private User.ProviderType providerType; // Added field
@Column(name = "provider_id")
private String providerId; // Added field
@Column(name = "created_at")
@CreationTimestamp
private OffsetDateTime createdAt;
@Column(name = "updated_at")
@UpdateTimestamp
private OffsetDateTime updatedAt;
}
1. AccountController:
Role: Handles HTTP requests related to user accounts.
Key Methods:
o createUserAccount: Creates a new user account using a Temporal workflow.
o getUserAccounts: Retrieves a list of existing accounts.
2. Account Model:
package com.midas.generated.model;
import java.net.URI;
import java.util.Objects;
import com.fasterxml.jackson.annotation.JsonProperty;
import com.fasterxml.jackson.annotation.JsonCreator;
import com.fasterxml.jackson.annotation.JsonTypeName;
import java.time.OffsetDateTime;
import jakarta.validation.Valid;
import jakarta.validation.constraints.*;
import io.swagger.v3.oas.annotations.media.Schema;
import java.util.*;
import jakarta.annotation.Generated;
/**
* CreateAccountDto
*/
@JsonTypeName("createAccount")
@Generated(value = "org.openapitools.codegen.languages.SpringCodegen", date =
"2024-02-06T00:41:20.524414800+05:30[Asia/Calcutta]")
public class CreateAccountDto {
/**
* User's first name
* @return firstName
*/
/**
* User's last name
* @return lastName
*/
@Override
public boolean equals(Object o) {
if (this == o) {
return true;
}
if (o == null || getClass() != o.getClass()) {
return false;
}
CreateAccountDto createAccount = (CreateAccountDto) o;
return Objects.equals(this.firstName, createAccount.firstName) &&
Objects.equals(this.lastName, createAccount.lastName) &&
Objects.equals(this.email, createAccount.email);
}
@Override
public int hashCode() {
return Objects.hash(firstName, lastName, email);
}
@Override
public String toString() {
StringBuilder sb = new StringBuilder();
sb.append("class CreateAccountDto {\n");
sb.append(" firstName:
").append(toIndentedString(firstName)).append("\n");
sb.append(" lastName:
").append(toIndentedString(lastName)).append("\n");
sb.append(" email: ").append(toIndentedString(email)).append("\n");
sb.append("}");
return sb.toString();
}
/**
* Convert the given object to string with each line indented by 4 spaces
* (except the first line).
*/
private String toIndentedString(Object o) {
if (o == null) {
return "null";
}
return o.toString().replace("\n", "\n ");
}
}
Purpose:
This class serves as a data transfer object (DTO) to encapsulate information required
for creating a new user account. It acts as a carrier of data between different parts of
the application.
Key Fields:
firstName: Stores the user's first name (String).
lastName: Stores the user's last name (String).
email: Stores the user's email address (String).
Annotations:
@JsonTypeName("createAccount"): This annotation from Jackson library designates a
logical type name for this DTO, useful for serialization and deserialization.
@Generated: Indicates that the code was generated automatically, likely using a tool
like Spring Codegen.
@Schema: Annotations from OpenAPI 3 for defining API documentation elements, such
as examples and descriptions.
@JsonProperty: Specifies the names of properties for JSON serialization and
deserialization.
Generated Methods:
Getters and Setters: Standard methods for accessing and modifying the fields of the
DTO.
equals() and hashCode(): Methods for comparing objects and generating hash codes,
used for operations like checking object equality and creating hash-based collections.
toString(): Provides a string representation of the DTO, primarily for debugging and
logging purposes.
Key Points:
This DTO is likely used by controllers or services to receive account creation requests
and transfer the data within the application.
It doesn't contain any business logic or processing itself; it's solely a data structure for
information exchange.